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/runtime/JSImmediate.h

    r39670 r39738  
    8383     */
    8484
     85    /*
     86     * On 64-bit platforms, we support an alternative encoding form for immediates, if
     87     * USE(ALTERNATE_JSIMMEDIATE) is defined.
     88     *
     89     * The top 16-bits denote the type:
     90     *
     91     * Pointer: 0000:PPPP:PPPP:PPPP
     92     * Integer: FFFF:0000:IIII:IIII
     93     *
     94     * 32-bit signed integers are marked with the 16-bit tag '0xFFFF'.  The tag '0x0000'
     95     * denotes a pointer, or another form of tagged immediate.  Boolean, null and undefined
     96     * values are encoded in the same manner as the default format.
     97     */
     98
    8599    class JSImmediate {
    86100    private:
    87101        friend class JIT;
    88102   
    89         static const int32_t TagMask           = 0x3; // primary tag is 2 bits long
    90         static const int32_t TagBitTypeInteger = 0x1; // bottom bit set indicates integer, this dominates the following bit
    91         static const int32_t TagBitTypeOther   = 0x2; // second bit set indicates immediate other than an integer
    92 
    93         static const int32_t ExtendedTagMask         = 0xC; // extended tag holds a further two bits
    94         static const int32_t ExtendedTagBitBool      = 0x4;
    95         static const int32_t ExtendedTagBitUndefined = 0x8;
    96 
    97         static const int32_t FullTagTypeMask      = TagMask | ExtendedTagMask;
    98         static const int32_t FullTagTypeBool      = TagBitTypeOther | ExtendedTagBitBool;
    99         static const int32_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
    100         static const int32_t FullTagTypeNull      = TagBitTypeOther;
    101 
     103#if USE(ALTERNATE_JSIMMEDIATE)
     104        static const intptr_t TagTypeInteger = 0xffff000000000000ll; // bottom bit set indicates integer, this dominates the following bit
     105#else
     106        static const intptr_t TagTypeInteger = 0x1; // bottom bit set indicates integer, this dominates the following bit
     107#endif
     108        static const intptr_t TagBitTypeOther   = 0x2; // second bit set indicates immediate other than an integer
     109        static const intptr_t TagMask           = TagTypeInteger | TagBitTypeOther;
     110
     111        static const intptr_t ExtendedTagMask         = 0xC; // extended tag holds a further two bits
     112        static const intptr_t ExtendedTagBitBool      = 0x4;
     113        static const intptr_t ExtendedTagBitUndefined = 0x8;
     114
     115        static const intptr_t FullTagTypeMask      = TagMask | ExtendedTagMask;
     116        static const intptr_t FullTagTypeBool      = TagBitTypeOther | ExtendedTagBitBool;
     117        static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
     118        static const intptr_t FullTagTypeNull      = TagBitTypeOther;
     119
     120#if USE(ALTERNATE_JSIMMEDIATE)
     121        static const int32_t IntegerPayloadShift  = 0;
     122#else
    102123        static const int32_t IntegerPayloadShift  = 1;
     124#endif
    103125        static const int32_t ExtendedPayloadShift = 4;
    104126
    105         static const int32_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
    106 
    107 #if USE(ALTERNATE_JSIMMEDIATE)
    108         static const intptr_t signBit = 0x100000000ll;
    109 #else
     127        static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
     128
    110129        static const int32_t signBit = 0x80000000;
    111 #endif
    112130 
    113131    public:
     
    119137        static ALWAYS_INLINE bool isNumber(JSValuePtr v)
    120138        {
    121             return rawValue(v) & TagBitTypeInteger;
     139            return rawValue(v) & TagTypeInteger;
    122140        }
    123141
     
    125143        {
    126144            // A single mask to check for the sign bit and the number tag all at once.
    127             return (rawValue(v) & (signBit | TagBitTypeInteger)) == TagBitTypeInteger;
     145            return (rawValue(v) & (signBit | TagTypeInteger)) == TagTypeInteger;
    128146        }
    129147       
     
    175193        static ALWAYS_INLINE bool areBothImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    176194        {
    177             return rawValue(v1) & rawValue(v2) & TagBitTypeInteger;
     195            return rawValue(v1) & rawValue(v2) & TagTypeInteger;
    178196        }
    179197
     
    187205        {
    188206            ASSERT(areBothImmediateNumbers(v1, v2));
    189             return makeValue((rawValue(v1) ^ rawValue(v2)) | TagBitTypeInteger);
     207            return makeValue((rawValue(v1) ^ rawValue(v2)) | TagTypeInteger);
    190208        }
    191209
     
    199217        {
    200218            ASSERT(areBothImmediateNumbers(val, shift));
    201             return makeValue((rawValue(val) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagBitTypeInteger);
     219#if USE(ALTERNATE_JSIMMEDIATE)
     220            return makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f))) | TagTypeInteger);
     221#else
     222            return makeValue((rawValue(val) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagTypeInteger);
     223#endif
    202224        }
    203225
     
    206228            // Number is non-negative and an operation involving two of these can't overflow.
    207229            // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
    208             return (rawValue(v) & (TagBitTypeInteger + (signBit | (signBit >> 1)))) == TagBitTypeInteger;
     230            return (rawValue(v) & (TagTypeInteger + (signBit | (signBit >> 1)))) == TagTypeInteger;
    209231        }
    210232
     
    213235            ASSERT(canDoFastAdditiveOperations(v1));
    214236            ASSERT(canDoFastAdditiveOperations(v2));
    215             return makeValue(rawValue(v1) + rawValue(v2) - TagBitTypeInteger);
     237            return makeValue(rawValue(v1) + rawValue(v2) - TagTypeInteger);
    216238        }
    217239
     
    220242            ASSERT(canDoFastAdditiveOperations(v1));
    221243            ASSERT(canDoFastAdditiveOperations(v2));
    222             return makeValue(rawValue(v1) - rawValue(v2) + TagBitTypeInteger);
     244            return makeValue(rawValue(v1) - rawValue(v2) + TagTypeInteger);
    223245        }
    224246
     
    274296        }
    275297
     298#if USE(ALTERNATE_JSIMMEDIATE)
     299        static ALWAYS_INLINE JSValuePtr makeInt(uint32_t value)
     300#else
    276301        static ALWAYS_INLINE JSValuePtr makeInt(int32_t value)
    277         {
    278             return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagBitTypeInteger);
     302#endif
     303        {
     304            return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeInteger);
    279305        }
    280306       
     
    331357        ASSERT(isImmediate(v));
    332358        intptr_t bits = rawValue(v);
    333         return (bits & TagBitTypeInteger)
    334             ? bits != TagBitTypeInteger // !0 ints
     359        return (bits & TagTypeInteger)
     360            ? bits != TagTypeInteger // !0 ints
    335361            : bits == (FullTagTypeBool | ExtendedPayloadBitBoolValue); // bool true
    336362    }
Note: See TracChangeset for help on using the changeset viewer.