Ignore:
Timestamp:
Jan 15, 2009, 7:20:35 PM (16 years ago)
Author:
[email protected]
Message:

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

Reviewed by Geoff Garen.

On x86-64 allow JSImmediate to encode 64-bit double precision values.
This patch only affects builds that set USE(ALTERNATE_JSIMMEDIATE).

Updates the implementation of JSValuePtr
and JSImmediate:: methods that operate on neumeric values to be be aware of the new representation. When this representation is in use, the class JSNumberCell is redundant and is compiled out.

The format of the new immediate representation is documented in JSImmediate.h.

  • JavaScriptCore.exp:
  • assembler/MacroAssembler.h: (JSC::MacroAssembler::subPtr):
  • assembler/X86Assembler.h: (JSC::X86Assembler::): (JSC::X86Assembler::subq_rr): (JSC::X86Assembler::movq_rr): (JSC::X86Assembler::ucomisd_rr): (JSC::X86Assembler::X86InstructionFormatter::twoByteOp64):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::cti_op_stricteq): (JSC::Interpreter::cti_op_nstricteq):
  • jit/JIT.cpp: (JSC::JIT::compileOpStrictEq): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_lshift): (JSC::JIT::compileFastArith_op_rshift): (JSC::JIT::compileFastArith_op_bitand): (JSC::JIT::compileFastArith_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/JITInlineMethods.h: (JSC::JIT::emitJumpIfBothJSCells): (JSC::JIT::emitJumpIfEitherNumber): (JSC::JIT::emitJumpIfNotEitherNumber): (JSC::JIT::emitJumpIfImmediateIntegerNumber): (JSC::JIT::emitJumpIfNotImmediateIntegerNumber): (JSC::JIT::emitJumpIfNotImmediateIntegerNumbers): (JSC::JIT::emitJumpSlowCaseIfNotImmediateIntegerNumber): (JSC::JIT::emitJumpSlowCaseIfNotImmediateIntegerNumbers): (JSC::JIT::emitFastArithDeTagImmediate): (JSC::JIT::emitFastArithDeTagImmediateJumpIfZero): (JSC::JIT::emitFastArithReTagImmediate): (JSC::JIT::emitFastArithIntToImmNoCheck):
  • runtime/JSCell.h:
  • runtime/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • runtime/JSImmediate.cpp: (JSC::JSImmediate::toThisObject): (JSC::JSImmediate::toObject): (JSC::JSImmediate::toString):
  • runtime/JSImmediate.h: (JSC::wtf_reinterpret_cast): (JSC::JSImmediate::isNumber): (JSC::JSImmediate::isIntegerNumber): (JSC::JSImmediate::isDoubleNumber): (JSC::JSImmediate::isPositiveIntegerNumber): (JSC::JSImmediate::areBothImmediateIntegerNumbers): (JSC::JSImmediate::makeInt): (JSC::JSImmediate::makeDouble): (JSC::JSImmediate::doubleValue): (JSC::doubleToBoolean): (JSC::JSImmediate::toBoolean): (JSC::JSImmediate::getTruncatedUInt32): (JSC::JSImmediate::makeOutOfIntegerRange): (JSC::JSImmediate::from): (JSC::JSImmediate::getTruncatedInt32): (JSC::JSImmediate::toDouble): (JSC::JSImmediate::getUInt32): (JSC::JSValuePtr::isInt32Fast): (JSC::JSValuePtr::isUInt32Fast): (JSC::JSValuePtr::areBothInt32Fast): (JSC::JSFastMath::canDoFastBitwiseOperations): (JSC::JSFastMath::xorImmediateNumbers): (JSC::JSFastMath::canDoFastRshift): (JSC::JSFastMath::canDoFastUrshift): (JSC::JSFastMath::rightShiftImmediateNumbers): (JSC::JSFastMath::canDoFastAdditiveOperations): (JSC::JSFastMath::addImmediateNumbers): (JSC::JSFastMath::subImmediateNumbers):
  • runtime/JSNumberCell.cpp: (JSC::jsNumberCell):
  • runtime/JSNumberCell.h: (JSC::createNumberStructure): (JSC::isNumberCell): (JSC::asNumberCell): (JSC::jsNumber): (JSC::JSValuePtr::isDoubleNumber): (JSC::JSValuePtr::getDoubleNumber): (JSC::JSValuePtr::isNumber): (JSC::JSValuePtr::uncheckedGetNumber): (JSC::jsNaN): (JSC::JSValuePtr::getNumber): (JSC::JSValuePtr::numberToInt32): (JSC::JSValuePtr::numberToUInt32):
  • runtime/JSValue.h:
  • runtime/NumberConstructor.cpp: (JSC::numberConstructorNegInfinity): (JSC::numberConstructorPosInfinity): (JSC::numberConstructorMaxValue): (JSC::numberConstructorMinValue):
  • runtime/NumberObject.cpp: (JSC::constructNumber):
  • runtime/NumberObject.h:
  • runtime/Operations.h: (JSC::JSValuePtr::equal): (JSC::JSValuePtr::equalSlowCaseInline): (JSC::JSValuePtr::strictEqual): (JSC::JSValuePtr::strictEqualSlowCaseInline):
  • wtf/Platform.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/JSNumberCell.h

    r39851 r39958  
    3333namespace JSC {
    3434
     35    extern const double NaN;
     36    extern const double Inf;
     37
     38#if !USE(ALTERNATE_JSIMMEDIATE)
     39
    3540    class Identifier;
    3641    class JSCell;
     
    4550        friend class JIT;
    4651        friend JSValuePtr jsNumberCell(JSGlobalData*, double);
    47         friend JSValuePtr jsNaN(JSGlobalData*);
    4852        friend JSValuePtr jsNumberCell(ExecState*, double);
    49         friend JSValuePtr jsNaN(ExecState*);
    5053    public:
    5154        double value() const { return m_value; }
     
    6164        virtual JSObject* toThisObject(ExecState*) const;
    6265        virtual JSValuePtr getJSNumber();
    63 
    64         int32_t toInt32() const;
    65         uint32_t toUInt32() const;
    6666
    6767        void* operator new(size_t size, ExecState* exec)
     
    105105    };
    106106
    107     extern const double NaN;
    108     extern const double Inf;
    109 
    110107    JSValuePtr jsNumberCell(JSGlobalData*, double);
    111     JSValuePtr jsNaN(JSGlobalData*);
    112108    JSValuePtr jsNumberCell(ExecState*, double);
    113     JSValuePtr jsNaN(ExecState*);
    114 
    115     inline JSNumberCell* JSValuePtr::asNumberCell() const
    116     {
    117         ASSERT(isNumberCell());
    118         return static_cast<JSNumberCell*>(asCell());
     109
     110    inline bool isNumberCell(JSValuePtr v)
     111    {
     112        return v.isCell() && v.asCell()->isNumber();
     113    }
     114
     115    inline JSNumberCell* asNumberCell(JSValuePtr v)
     116    {
     117        ASSERT(isNumberCell(v));
     118        return static_cast<JSNumberCell*>(v.asCell());
    119119    }
    120120
     
    125125    }
    126126
    127     ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
    128     {
    129         ASSERT(JSImmediate::from(i));
    130         return JSImmediate::from(i);
    131     }
    132 
    133     ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
    134     {
    135         ASSERT(JSImmediate::from(i));
    136         return JSImmediate::from(i);
    137     }
    138 
    139     ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
    140     {
    141         ASSERT(JSImmediate::from(i));
    142         return JSImmediate::from(i);
    143     }
    144 
    145     ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
    146     {
    147         ASSERT(JSImmediate::from(i));
    148         return JSImmediate::from(i);
    149     }
    150 
    151127    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
    152128    {
     
    191167    }
    192168
    193     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, short i)
     169    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
    194170    {
    195171        JSValuePtr v = JSImmediate::from(i);
     
    197173    }
    198174
    199     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i)
     175    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
    200176    {
    201177        JSValuePtr v = JSImmediate::from(i);
     
    203179    }
    204180
    205     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
     181    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
    206182    {
    207183        JSValuePtr v = JSImmediate::from(i);
     
    209185    }
    210186
    211     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
     187    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
    212188    {
    213189        JSValuePtr v = JSImmediate::from(i);
     
    215191    }
    216192
    217     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
    218     {
    219         JSValuePtr v = JSImmediate::from(i);
    220         return v ? v : jsNumberCell(globalData, i);
    221     }
    222 
    223     ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
    224     {
    225         JSValuePtr v = JSImmediate::from(i);
    226         return v ? v : jsNumberCell(globalData, i);
    227     }
    228 
    229193    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
    230194    {
     
    239203    }
    240204
     205    inline bool JSValuePtr::isDoubleNumber() const
     206    {
     207        return isNumberCell(asValue());
     208    }
     209
     210    inline double JSValuePtr::getDoubleNumber() const
     211    {
     212        return asNumberCell(asValue())->value();
     213    }
     214
     215    inline bool JSValuePtr::isNumber() const
     216    {
     217        return JSImmediate::isNumber(asValue()) || isDoubleNumber();
     218    }
     219
     220    inline double JSValuePtr::uncheckedGetNumber() const
     221    {
     222        ASSERT(isNumber());
     223        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
     224    }
     225
     226#else
     227
     228    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d)
     229    {
     230        JSValuePtr v = JSImmediate::from(d);
     231        ASSERT(v);
     232        return v;
     233    }
     234
     235    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i)
     236    {
     237        JSValuePtr v = JSImmediate::from(i);
     238        ASSERT(v);
     239        return v;
     240    }
     241
     242    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i)
     243    {
     244        JSValuePtr v = JSImmediate::from(i);
     245        ASSERT(v);
     246        return v;
     247    }
     248
     249    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i)
     250    {
     251        JSValuePtr v = JSImmediate::from(i);
     252        ASSERT(v);
     253        return v;
     254    }
     255
     256    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i)
     257    {
     258        JSValuePtr v = JSImmediate::from(i);
     259        ASSERT(v);
     260        return v;
     261    }
     262
     263    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i)
     264    {
     265        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
     266        ASSERT(v);
     267        return v;
     268    }
     269
     270    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i)
     271    {
     272        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
     273        ASSERT(v);
     274        return v;
     275    }
     276
     277    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d)
     278    {
     279        JSValuePtr v = JSImmediate::from(d);
     280        ASSERT(v);
     281        return v;
     282    }
     283
     284    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i)
     285    {
     286        JSValuePtr v = JSImmediate::from(i);
     287        ASSERT(v);
     288        return v;
     289    }
     290
     291    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i)
     292    {
     293        JSValuePtr v = JSImmediate::from(i);
     294        ASSERT(v);
     295        return v;
     296    }
     297
     298    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i)
     299    {
     300        JSValuePtr v = JSImmediate::from(i);
     301        ASSERT(v);
     302        return v;
     303    }
     304
     305    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i)
     306    {
     307        JSValuePtr v = JSImmediate::from(i);
     308        ASSERT(v);
     309        return v;
     310    }
     311
     312    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i)
     313    {
     314        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
     315        ASSERT(v);
     316        return v;
     317    }
     318
     319    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i)
     320    {
     321        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
     322        ASSERT(v);
     323        return v;
     324    }
     325
     326    inline bool JSValuePtr::isDoubleNumber() const
     327    {
     328        return JSImmediate::isDoubleNumber(asValue());
     329    }
     330
     331    inline double JSValuePtr::getDoubleNumber() const
     332    {
     333        return JSImmediate::doubleValue(asValue());
     334    }
     335
     336    inline bool JSValuePtr::isNumber() const
     337    {
     338        return JSImmediate::isNumber(asValue());
     339    }
     340
     341    inline double JSValuePtr::uncheckedGetNumber() const
     342    {
     343        ASSERT(isNumber());
     344        return JSImmediate::toDouble(asValue());
     345    }
     346
     347#endif
     348
     349    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
     350    {
     351        ASSERT(JSImmediate::from(i));
     352        return JSImmediate::from(i);
     353    }
     354
     355    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
     356    {
     357        ASSERT(JSImmediate::from(i));
     358        return JSImmediate::from(i);
     359    }
     360
     361    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
     362    {
     363        ASSERT(JSImmediate::from(i));
     364        return JSImmediate::from(i);
     365    }
     366
     367    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
     368    {
     369        ASSERT(JSImmediate::from(i));
     370        return JSImmediate::from(i);
     371    }
     372
     373    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i)
     374    {
     375        ASSERT(JSImmediate::from(i));
     376        return JSImmediate::from(i);
     377    }
     378
     379    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i)
     380    {
     381        ASSERT(JSImmediate::from(i));
     382        return JSImmediate::from(i);
     383    }
     384
     385    inline JSValuePtr jsNaN(ExecState* exec)
     386    {
     387        return jsNumber(exec, NaN);
     388    }
     389
     390    inline JSValuePtr jsNaN(JSGlobalData* globalData)
     391    {
     392        return jsNumber(globalData, NaN);
     393    }
     394
    241395    // --- JSValue inlines ----------------------------
    242 
    243     inline double JSValuePtr::uncheckedGetNumber() const
    244     {
    245         ASSERT(isNumber());
    246         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell()->value();
    247     }
    248 
    249     inline int32_t JSNumberCell::toInt32() const
    250     {
    251         if (m_value >= -2147483648.0 && m_value < 2147483648.0)
    252             return static_cast<int32_t>(m_value);
    253         bool ignored;
    254         return toInt32SlowCase(m_value, ignored);
    255     }
    256 
    257     inline uint32_t JSNumberCell::toUInt32() const
    258     {
    259         if (m_value >= 0.0 && m_value < 4294967296.0)
    260             return static_cast<uint32_t>(m_value);
    261         bool ignored;
    262         return toUInt32SlowCase(m_value, ignored);
    263     }
    264396
    265397    ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
     
    272404        if (isInt32Fast())
    273405            result = getInt32Fast();
    274         else if (LIKELY(isNumberCell()))
    275             result = asNumberCell()->value();
     406        else if (LIKELY(isDoubleNumber()))
     407            result = getDoubleNumber();
    276408        else {
    277409            ASSERT(!isNumber());
     
    285417        if (isInt32Fast())
    286418            arg = getInt32Fast();
    287         else if (LIKELY(isNumberCell()))
    288             arg = asNumberCell()->toInt32();
     419        else if (LIKELY(isDoubleNumber()))
     420            arg = JSC::toInt32(getDoubleNumber());
    289421        else {
    290422            ASSERT(!isNumber());
     
    298430        if (isUInt32Fast())
    299431            arg = getUInt32Fast();
    300         else if (LIKELY(isNumberCell()))
    301             arg = asNumberCell()->toUInt32();
     432        else if (LIKELY(isDoubleNumber()))
     433            arg = JSC::toUInt32(getDoubleNumber());
    302434        else if (isInt32Fast()) {
    303435            // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
Note: See TracChangeset for help on using the changeset viewer.