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/JITArithmetic.cpp

    r39670 r39738  
    6161#endif
    6262    lshift32(X86::ecx, X86::eax);
    63 #if USE(ALTERNATE_JSIMMEDIATE)
    64     emitFastArithIntToImmNoCheck(X86::eax);
    65 #else
     63#if !USE(ALTERNATE_JSIMMEDIATE)
    6664    addSlowCase(joAdd32(X86::eax, X86::eax));
    6765    signExtend32ToPtr(X86::eax, X86::eax);
    68     emitFastArithReTagImmediate(X86::eax);
    69 #endif
     66#endif
     67    emitFastArithReTagImmediate(X86::eax, X86::eax);
    7068    emitPutVirtualRegister(result);
    7169}
     
    9896        emitJumpSlowCaseIfNotImmNum(X86::eax);
    9997        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
     98#if USE(ALTERNATE_JSIMMEDIATE)
     99        rshift32(Imm32(JSImmediate::getTruncatedUInt32(getConstantOperand(op2)) & 0x1f), X86::eax);
     100#else
    100101        rshiftPtr(Imm32(JSImmediate::getTruncatedUInt32(getConstantOperand(op2)) & 0x1f), X86::eax);
     102#endif
    101103    } else {
    102104        emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
     
    109111        and32(Imm32(0x1f), X86::ecx);
    110112#endif
     113#if USE(ALTERNATE_JSIMMEDIATE)
     114        rshift32(X86::ecx, X86::eax);
     115#else
    111116        rshiftPtr(X86::ecx, X86::eax);
    112     }
    113     orPtr(Imm32(JSImmediate::TagBitTypeInteger), X86::eax);
     117#endif
     118    }
     119#if USE(ALTERNATE_JSIMMEDIATE)
     120    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     121#else
     122    orPtr(Imm32(JSImmediate::TagTypeInteger), X86::eax);
     123#endif
    114124    emitPutVirtualRegister(result);
    115125}
     
    131141void JIT::compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2)
    132142{
    133     if (isOperandConstant31BitImmediateInt(op1)) {
     143    if (isOperandConstantImmediateInt(op1)) {
    134144        emitGetVirtualRegister(op2, X86::eax);
    135145        emitJumpSlowCaseIfNotImmNum(X86::eax);
     146#if USE(ALTERNATE_JSIMMEDIATE)
     147        int32_t imm = JSImmediate::intValue(getConstantOperand(op1));
     148        andPtr(Imm32(imm), X86::eax);
     149        if (imm >= 0)
     150            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     151#else
    136152        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), X86::eax);
    137     } else if (isOperandConstant31BitImmediateInt(op2)) {
     153#endif
     154    } else if (isOperandConstantImmediateInt(op2)) {
    138155        emitGetVirtualRegister(op1, X86::eax);
    139156        emitJumpSlowCaseIfNotImmNum(X86::eax);
     157#if USE(ALTERNATE_JSIMMEDIATE)
     158        int32_t imm = JSImmediate::intValue(getConstantOperand(op2));
     159        andPtr(Imm32(imm), X86::eax);
     160        if (imm >= 0)
     161            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     162#else
    140163        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), X86::eax);
     164#endif
    141165    } else {
    142166        emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
     
    149173{
    150174    linkSlowCase(iter);
    151     if (isOperandConstant31BitImmediateInt(op1)) {
     175    if (isOperandConstantImmediateInt(op1)) {
    152176        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    153177        emitPutJITStubArg(X86::eax, 2);
    154     } else if (isOperandConstant31BitImmediateInt(op2)) {
     178    } else if (isOperandConstantImmediateInt(op2)) {
    155179        emitPutJITStubArg(X86::eax, 1);
    156180        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     
    169193    emitJumpSlowCaseIfNotImmNum(X86::ecx);
    170194#if USE(ALTERNATE_JSIMMEDIATE)
    171     addSlowCase(jePtr(X86::ecx, ImmPtr(JSImmediate::zeroImmediate())));
    172     emitFastArithImmToInt(X86::eax);
    173     emitFastArithImmToInt(X86::ecx);
     195    addSlowCase(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(JSImmediate::zeroImmediate()))));
    174196    mod32(X86::ecx, X86::eax, X86::edx);
    175     emitFastArithIntToImmNoCheck(X86::edx);
    176197#else
    177198    emitFastArithDeTagImmediate(X86::eax);
     
    179200    mod32(X86::ecx, X86::eax, X86::edx);
    180201    signExtend32ToPtr(X86::edx, X86::edx);
    181     emitFastArithReTagImmediate(X86::edx);
    182 #endif
    183     move(X86::edx, X86::eax);
     202#endif
     203    emitFastArithReTagImmediate(X86::edx, X86::eax);
    184204    emitPutVirtualRegister(result);
    185205}
     
    194214    Jump notImm2 = getSlowCase(iter);
    195215    linkSlowCase(iter);
    196     emitFastArithReTagImmediate(X86::eax);
    197     emitFastArithReTagImmediate(X86::ecx);
     216    emitFastArithReTagImmediate(X86::eax, X86::eax);
     217    emitFastArithReTagImmediate(X86::ecx, X86::ecx);
    198218    notImm1.link(this);
    199219    notImm2.link(this);
     
    217237        // FIXME: investigate performing a 31-bit add here (can we preserve upper bit & detect overflow from low word to high?)
    218238        //        (or, detect carry? - if const is positive, will only carry when overflowing from negative to positive?)
    219         emitFastArithImmToInt(X86::eax);
    220239        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
    221         emitFastArithIntToImmNoCheck(X86::eax);
     240        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    222241#else
    223242        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
     
    231250        emitFastArithImmToInt(X86::eax);
    232251        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
    233         emitFastArithIntToImmNoCheck(X86::eax);
     252        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    234253#else
    235254        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
     
    306325        emitJumpSlowCaseIfNotImmNum(X86::eax);
    307326#if USE(ALTERNATE_JSIMMEDIATE)
    308         emitFastArithImmToInt(X86::eax);
    309327        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    310         emitFastArithIntToImmNoCheck(X86::eax);
    311328#else
    312329        emitFastArithDeTagImmediate(X86::eax);
    313330        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    314331        signExtend32ToPtr(X86::eax, X86::eax);
    315         emitFastArithReTagImmediate(X86::eax);
    316 #endif
     332#endif
     333        emitFastArithReTagImmediate(X86::eax, X86::eax);
    317334        emitPutVirtualRegister(result);
    318335    } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
     
    320337        emitJumpSlowCaseIfNotImmNum(X86::eax);
    321338#if USE(ALTERNATE_JSIMMEDIATE)
    322         emitFastArithImmToInt(X86::eax);
    323339        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    324         emitFastArithIntToImmNoCheck(X86::eax);
    325340#else
    326341        emitFastArithDeTagImmediate(X86::eax);
    327342        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    328343        signExtend32ToPtr(X86::eax, X86::eax);
    329         emitFastArithReTagImmediate(X86::eax);
    330 #endif
     344#endif
     345        emitFastArithReTagImmediate(X86::eax, X86::eax);
    331346        emitPutVirtualRegister(result);
    332347    } else
     
    358373    emitJumpSlowCaseIfNotImmNum(X86::eax);
    359374#if USE(ALTERNATE_JSIMMEDIATE)
    360     emitFastArithImmToInt(X86::edx);
    361375    addSlowCase(joAdd32(Imm32(1), X86::edx));
    362     emitFastArithIntToImmNoCheck(X86::edx);
     376    emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
    363377#else
    364378    addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
     
    384398    emitJumpSlowCaseIfNotImmNum(X86::eax);
    385399#if USE(ALTERNATE_JSIMMEDIATE)
    386     emitFastArithImmToInt(X86::edx);
    387400    addSlowCase(joSub32(Imm32(1), X86::edx));
    388     emitFastArithIntToImmNoCheck(X86::edx);
     401    emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
    389402#else
    390403    addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
     
    409422    emitJumpSlowCaseIfNotImmNum(X86::eax);
    410423#if USE(ALTERNATE_JSIMMEDIATE)
    411     emitFastArithImmToInt(X86::eax);
    412424    // FIXME: Could add ptr & specify int64; no need to re-sign-extend?
    413425    addSlowCase(joAdd32(Imm32(1), X86::eax));
    414     emitFastArithIntToImmNoCheck(X86::eax);
     426    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    415427#else
    416428    addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
     
    435447    emitJumpSlowCaseIfNotImmNum(X86::eax);
    436448#if USE(ALTERNATE_JSIMMEDIATE)
    437     emitFastArithImmToInt(X86::eax);
    438449    addSlowCase(joSub32(Imm32(1), X86::eax));
    439     emitFastArithIntToImmNoCheck(X86::eax);
     450    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    440451#else
    441452    addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
     
    556567    __ link(__ je(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
    557568    // Yes it really really really is representable as a JSImmediate.
    558     emitFastArithIntToImmNoCheck(tempReg1);
    559     if (tempReg1 != X86::eax)
    560         __ movl_rr(tempReg1, X86::eax);
     569    emitFastArithIntToImmNoCheck(tempReg1, X86::eax);
    561570    emitPutVirtualRegister(dst);
    562571}
     
    576585
    577586        // Check op2 is a number
    578         __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
     587        __ testl_i32r(JSImmediate::TagTypeInteger, X86::edx);
    579588        JmpSrc op2imm = __ jne();
    580589        if (!types.second().definitelyIsNumber()) {
     
    586595        // (1) In this case src2 is a reusable number cell.
    587596        //     Slow case if src1 is not a number type.
    588         __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
     597        __ testl_i32r(JSImmediate::TagTypeInteger, X86::eax);
    589598        JmpSrc op1imm = __ jne();
    590599        if (!types.first().definitelyIsNumber()) {
     
    623632
    624633        // Check op1 is a number
    625         __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
     634        __ testl_i32r(JSImmediate::TagTypeInteger, X86::eax);
    626635        JmpSrc op1imm = __ jne();
    627636        if (!types.first().definitelyIsNumber()) {
     
    633642        // (1) In this case src1 is a reusable number cell.
    634643        //     Slow case if src2 is not a number type.
    635         __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
     644        __ testl_i32r(JSImmediate::TagTypeInteger, X86::edx);
    636645        JmpSrc op2imm = __ jne();
    637646        if (!types.second().definitelyIsNumber()) {
     
    680689        addSlowCase(__ jo());
    681690        signExtend32ToPtr(X86::eax, X86::eax);
    682         emitFastArithReTagImmediate(X86::eax);
     691        emitFastArithReTagImmediate(X86::eax, X86::eax);
    683692    } else {
    684693        ASSERT(opcodeID == op_mul);
     
    699708        addSlowCase(__ jo());
    700709        signExtend32ToPtr(X86::eax, X86::eax);
    701         emitFastArithReTagImmediate(X86::eax);
     710        emitFastArithReTagImmediate(X86::eax, X86::eax);
    702711    }
    703712    emitPutVirtualRegister(dst);
Note: See TracChangeset for help on using the changeset viewer.