Changeset 39851 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Jan 12, 2009, 8:51:16 PM (16 years ago)
Author:
[email protected]
Message:

JavaScriptCore:

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

Reviewed by Oliver Hunt.

Make the JSImmediate interface private.

All manipulation of JS values should be through the JSValuePtr class, not by using JSImmediate
directly. The key missing methods on JSValuePtr are:

  • isCell() - check for values that are JSCell*s, and as such where asCell() may be used.
  • isInt32Fast() getInt32Fast() - fast check/access for integer immediates.
  • isUInt32Fast() getUInt32Fast() - ditto for unsigned integer immediates.

The JIT is allowed full access to JSImmediate, since it needs to be able to directly
manipulate JSValuePtrs. The Interpreter is provided access to perform operations directly
on JSValuePtrs through the new JSFastMath interface.

No performance impact.

  • API/JSCallbackObjectFunctions.h: (JSC::::toNumber):
  • API/JSValueRef.cpp: (JSValueIsEqual): (JSValueIsStrictEqual):
  • JavaScriptCore.exp:
  • bytecode/CodeBlock.h: (JSC::CodeBlock::isKnownNotImmediate):
  • bytecompiler/BytecodeGenerator.cpp: (JSC::keyForImmediateSwitch):
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::JSValueHashTraits::constructDeletedValue): (JSC::BytecodeGenerator::JSValueHashTraits::isDeletedValue):
  • interpreter/Interpreter.cpp: (JSC::jsLess): (JSC::jsLessEq): (JSC::jsAdd): (JSC::jsIsObjectType): (JSC::cachePrototypeChain): (JSC::Interpreter::tryCachePutByID): (JSC::Interpreter::tryCacheGetByID): (JSC::Interpreter::privateExecute): (JSC::Interpreter::tryCTICachePutByID): (JSC::Interpreter::tryCTICacheGetByID): (JSC::Interpreter::cti_op_add): (JSC::Interpreter::cti_op_get_by_id_self_fail): (JSC::Interpreter::cti_op_get_by_id_proto_list): (JSC::Interpreter::cti_op_instanceof): (JSC::Interpreter::cti_op_mul): (JSC::Interpreter::cti_op_get_by_val): (JSC::Interpreter::cti_op_get_by_val_byte_array): (JSC::Interpreter::cti_op_sub): (JSC::Interpreter::cti_op_put_by_val): (JSC::Interpreter::cti_op_put_by_val_array): (JSC::Interpreter::cti_op_put_by_val_byte_array): (JSC::Interpreter::cti_op_negate): (JSC::Interpreter::cti_op_div): (JSC::Interpreter::cti_op_eq): (JSC::Interpreter::cti_op_lshift): (JSC::Interpreter::cti_op_bitand): (JSC::Interpreter::cti_op_rshift): (JSC::Interpreter::cti_op_bitnot): (JSC::Interpreter::cti_op_neq): (JSC::Interpreter::cti_op_urshift): (JSC::Interpreter::cti_op_call_eval): (JSC::Interpreter::cti_op_throw): (JSC::Interpreter::cti_op_is_undefined): (JSC::Interpreter::cti_op_stricteq): (JSC::Interpreter::cti_op_nstricteq): (JSC::Interpreter::cti_op_switch_imm): (JSC::Interpreter::cti_vm_throw):
  • interpreter/Interpreter.h: (JSC::Interpreter::isJSArray): (JSC::Interpreter::isJSString): (JSC::Interpreter::isJSByteArray):
  • jit/JIT.cpp: (JSC::JIT::compileOpStrictEq): (JSC::JIT::privateCompileMainPass):
  • jit/JIT.h: (JSC::JIT::isStrictEqCaseHandledInJITCode):
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_rshift): (JSC::JIT::compileFastArith_op_bitand): (JSC::JIT::compileFastArith_op_mod):
  • jit/JITCall.cpp: (JSC::JIT::unlinkCall): (JSC::JIT::compileOpCall):
  • jit/JITInlineMethods.h: (JSC::JIT::getConstantOperandImmediateInt): (JSC::JIT::isOperandConstantImmediateInt):
  • parser/Nodes.cpp: (JSC::processClauseList):
  • runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncIndexOf): (JSC::arrayProtoFuncLastIndexOf):
  • runtime/BooleanPrototype.cpp: (JSC::booleanProtoFuncValueOf):
  • runtime/Collector.cpp: (JSC::Heap::protect): (JSC::Heap::unprotect): (JSC::Heap::heap):
  • runtime/JSByteArray.cpp: (JSC::JSByteArray::getOwnPropertySlot):
  • runtime/JSByteArray.h: (JSC::JSByteArray::getIndex):
  • runtime/JSCell.cpp:
  • runtime/JSCell.h: (JSC::JSValuePtr::isNumberCell): (JSC::JSValuePtr::asCell): (JSC::JSValuePtr::isNumber):
  • runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncParseInt):
  • runtime/JSImmediate.h: (JSC::js0): (JSC::jsImpossibleValue): (JSC::JSValuePtr::toInt32): (JSC::JSValuePtr::toUInt32): (JSC::JSValuePtr::isCell): (JSC::JSValuePtr::isInt32Fast): (JSC::JSValuePtr::getInt32Fast): (JSC::JSValuePtr::isUInt32Fast): (JSC::JSValuePtr::getUInt32Fast): (JSC::JSValuePtr::makeInt32Fast): (JSC::JSValuePtr::areBothInt32Fast): (JSC::JSFastMath::canDoFastBitwiseOperations): (JSC::JSFastMath::equal): (JSC::JSFastMath::notEqual): (JSC::JSFastMath::andImmediateNumbers): (JSC::JSFastMath::xorImmediateNumbers): (JSC::JSFastMath::orImmediateNumbers): (JSC::JSFastMath::canDoFastRshift): (JSC::JSFastMath::canDoFastUrshift): (JSC::JSFastMath::rightShiftImmediateNumbers): (JSC::JSFastMath::canDoFastAdditiveOperations): (JSC::JSFastMath::addImmediateNumbers): (JSC::JSFastMath::subImmediateNumbers): (JSC::JSFastMath::incImmediateNumber): (JSC::JSFastMath::decImmediateNumber):
  • runtime/JSNumberCell.h: (JSC::JSValuePtr::asNumberCell): (JSC::jsNumber): (JSC::JSValuePtr::uncheckedGetNumber): (JSC::JSNumberCell::toInt32): (JSC::JSNumberCell::toUInt32): (JSC::JSValuePtr::toJSNumber): (JSC::JSValuePtr::getNumber): (JSC::JSValuePtr::numberToInt32): (JSC::JSValuePtr::numberToUInt32):
  • runtime/JSObject.h: (JSC::JSValuePtr::isObject): (JSC::JSValuePtr::get): (JSC::JSValuePtr::put):
  • runtime/JSValue.cpp: (JSC::JSValuePtr::toInteger): (JSC::JSValuePtr::toIntegerPreserveNaN):
  • runtime/JSValue.h:
  • runtime/Operations.cpp: (JSC::JSValuePtr::equalSlowCase): (JSC::JSValuePtr::strictEqualSlowCase):
  • runtime/Operations.h: (JSC::JSValuePtr::equal): (JSC::JSValuePtr::equalSlowCaseInline): (JSC::JSValuePtr::strictEqual): (JSC::JSValuePtr::strictEqualSlowCaseInline):
  • runtime/Protect.h: (JSC::gcProtect): (JSC::gcUnprotect):
  • runtime/StringPrototype.cpp: (JSC::stringProtoFuncCharAt): (JSC::stringProtoFuncCharCodeAt):
  • runtime/Structure.cpp: (JSC::Structure::createCachedPrototypeChain):

WebCore:

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

Reviewed by Oliver Hunt.

Deprecate JSValuePtr::getNumber() - two ways to get a number should be enough.

  • bindings/js/JSSQLTransactionCustom.cpp: (WebCore::JSSQLTransaction::executeSql):
  • bindings/objc/WebScriptObject.mm: (+[WebScriptObject _convertValueToObjcValue:originRootObject:rootObject:]):

WebKit/mac:

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

Reviewed by Oliver Hunt.

Deprecate JSValuePtr::getNumber() - two ways to get a number should be enough.

  • WebView/WebView.mm: (aeDescFromJSValue):
Location:
trunk/JavaScriptCore/runtime
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/ArrayPrototype.cpp

    r39670 r39851  
    754754        if (!e)
    755755            continue;
    756         if (strictEqual(searchElement, e))
     756        if (JSValuePtr::strictEqual(searchElement, e))
    757757            return jsNumber(exec, index);
    758758    }
     
    785785        if (!e)
    786786            continue;
    787         if (strictEqual(searchElement, e))
     787        if (JSValuePtr::strictEqual(searchElement, e))
    788788            return jsNumber(exec, index);
    789789    }
  • trunk/JavaScriptCore/runtime/BooleanPrototype.cpp

    r39670 r39851  
    7171JSValuePtr booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
    7272{
    73     if (JSImmediate::isBoolean(thisValue))
     73    if (thisValue->isBoolean())
    7474        return thisValue;
    7575
  • trunk/JavaScriptCore/runtime/Collector.cpp

    r39707 r39851  
    809809    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
    810810
    811     if (JSImmediate::isImmediate(k))
     811    if (!k->isCell())
    812812        return;
    813813
     
    826826    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
    827827
    828     if (JSImmediate::isImmediate(k))
     828    if (!k->isCell())
    829829        return;
    830830
     
    840840Heap* Heap::heap(JSValuePtr v)
    841841{
    842     if (JSImmediate::isImmediate(v))
     842    if (!v->isCell())
    843843        return 0;
    844844    return Heap::cellBlock(v->asCell())->heap;
  • trunk/JavaScriptCore/runtime/JSByteArray.cpp

    r39670 r39851  
    5353    unsigned index = propertyName.toUInt32(&ok, false);
    5454    if (ok && canAccessIndex(index)) {
    55         slot.setValue(getIndex(index));
     55        slot.setValue(getIndex(exec, index));
    5656        return true;
    5757    }
     
    6262{
    6363    if (canAccessIndex(propertyName)) {
    64         slot.setValue(getIndex(propertyName));
     64        slot.setValue(getIndex(exec, propertyName));
    6565        return true;
    6666    }
  • trunk/JavaScriptCore/runtime/JSByteArray.h

    r39670 r39851  
    3636    public:
    3737        bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
    38         JSValuePtr getIndex(unsigned i)
     38        JSValuePtr getIndex(ExecState* exec, unsigned i)
    3939        {
    4040            ASSERT(canAccessIndex(i));
    41             return JSImmediate::from(m_storage->data()[i]);
     41            return jsNumber(exec, m_storage->data()[i]);
    4242        }
    4343
  • trunk/JavaScriptCore/runtime/JSCell.cpp

    r39670 r39851  
    101101}
    102102
    103 bool JSCell::getNumber(double& numericValue) const
    104 {
    105     if (!isNumber())
    106         return false;
    107     numericValue = static_cast<const JSNumberCell*>(this)->value();
    108     return true;
    109 }
    110 
    111 double JSCell::getNumber() const
    112 {
    113     return isNumber() ? static_cast<const JSNumberCell*>(this)->value() : NaN;
    114 }
    115 
    116103bool JSCell::getString(UString&stringValue) const
    117104{
  • trunk/JavaScriptCore/runtime/JSCell.h

    r39769 r39851  
    5858
    5959        // Extracting the value.
    60         bool getNumber(double&) const;
    61         double getNumber() const; // NaN if not a number
    6260        bool getString(UString&) const;
    6361        UString getString() const; // null string if not a string
     
    6967
    7068        // Extracting integer values.
     69        // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*.
    7170        virtual bool getUInt32(uint32_t&) const;
    7271        virtual bool getTruncatedInt32(int32_t&) const;
     
    131130    }
    132131
     132    inline bool JSValuePtr::isNumberCell() const
     133    {
     134        return isCell() && asCell()->isNumber();
     135    }
     136
    133137    inline bool JSCell::isObject() const
    134138    {
     
    158162    ALWAYS_INLINE JSCell* JSValuePtr::asCell() const
    159163    {
    160         ASSERT(!JSImmediate::isImmediate(asValue()));
     164        ASSERT(isCell());
    161165        return m_ptr;
    162166    }
     
    175179    inline bool JSValuePtr::isNumber() const
    176180    {
    177         return JSImmediate::isNumber(asValue()) || (!JSImmediate::isImmediate(asValue()) && asCell()->isNumber());
     181        return JSImmediate::isNumber(asValue()) || (isCell() && asCell()->isNumber());
    178182    }
    179183
     
    191195    {
    192196        return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
    193     }
    194 
    195     inline double JSValuePtr::getNumber() const
    196     {
    197         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->getNumber();
    198197    }
    199198
  • trunk/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r39670 r39851  
    300300
    301301    if (value->isNumber() && (radix == 0 || radix == 10)) {
    302         if (JSImmediate::isImmediate(value))
     302        if (value->isInt32Fast())
    303303            return value;
    304304        double d = value->uncheckedGetNumber();
    305305        if (!isfinite(d))
    306             return JSImmediate::zeroImmediate();
     306            return js0();
    307307        return jsNumber(exec, floor(d));
    308308    }
  • trunk/JavaScriptCore/runtime/JSImmediate.h

    r39769 r39851  
    3737    class ExecState;
    3838    class JSCell;
     39    class JSFastMath;
     40    class JSGlobalData;
    3941    class JSObject;
    4042    class UString;
     43
     44    JSValuePtr js0();
     45    JSValuePtr jsNull();
     46    JSValuePtr jsBoolean(bool b);
     47    JSValuePtr jsUndefined();
     48    JSValuePtr jsImpossibleValue();
     49    JSValuePtr jsNumber(ExecState* exec, double d);
     50    JSValuePtr jsNumber(ExecState*, char i);
     51    JSValuePtr jsNumber(ExecState*, unsigned char i);
     52    JSValuePtr jsNumber(ExecState*, short i);
     53    JSValuePtr jsNumber(ExecState*, unsigned short i);
     54    JSValuePtr jsNumber(ExecState* exec, int i);
     55    JSValuePtr jsNumber(ExecState* exec, unsigned i);
     56    JSValuePtr jsNumber(ExecState* exec, long i);
     57    JSValuePtr jsNumber(ExecState* exec, unsigned long i);
     58    JSValuePtr jsNumber(ExecState* exec, long long i);
     59    JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
     60    JSValuePtr jsNumber(JSGlobalData* globalData, double d);
     61    JSValuePtr jsNumber(JSGlobalData* globalData, short i);
     62    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
     63    JSValuePtr jsNumber(JSGlobalData* globalData, int i);
     64    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
     65    JSValuePtr jsNumber(JSGlobalData* globalData, long i);
     66    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
     67    JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
     68    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
    4169
    4270    /*
     
    99127    private:
    100128        friend class JIT;
    101    
     129        friend class JSValuePtr;
     130        friend class JSFastMath;
     131        friend JSValuePtr js0();
     132        friend JSValuePtr jsNull();
     133        friend JSValuePtr jsBoolean(bool b);
     134        friend JSValuePtr jsUndefined();
     135        friend JSValuePtr jsImpossibleValue();
     136        friend JSValuePtr jsNumber(ExecState* exec, double d);
     137        friend JSValuePtr jsNumber(ExecState*, char i);
     138        friend JSValuePtr jsNumber(ExecState*, unsigned char i);
     139        friend JSValuePtr jsNumber(ExecState*, short i);
     140        friend JSValuePtr jsNumber(ExecState*, unsigned short i);
     141        friend JSValuePtr jsNumber(ExecState* exec, int i);
     142        friend JSValuePtr jsNumber(ExecState* exec, unsigned i);
     143        friend JSValuePtr jsNumber(ExecState* exec, long i);
     144        friend JSValuePtr jsNumber(ExecState* exec, unsigned long i);
     145        friend JSValuePtr jsNumber(ExecState* exec, long long i);
     146        friend JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
     147        friend JSValuePtr jsNumber(JSGlobalData* globalData, double d);
     148        friend JSValuePtr jsNumber(JSGlobalData* globalData, short i);
     149        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
     150        friend JSValuePtr jsNumber(JSGlobalData* globalData, int i);
     151        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
     152        friend JSValuePtr jsNumber(JSGlobalData* globalData, long i);
     153        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
     154        friend JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
     155        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
     156
    102157#if USE(ALTERNATE_JSIMMEDIATE)
    103158        static const intptr_t TagTypeInteger = 0xffff000000000000ll; // bottom bit set indicates integer, this dominates the following bit
     
    128183        static const int32_t signBit = 0x80000000;
    129184 
    130     public:
    131185        static ALWAYS_INLINE bool isImmediate(JSValuePtr v)
    132186        {
     
    180234        }
    181235
    182         static ALWAYS_INLINE bool isAnyImmediate(JSValuePtr v1, JSValuePtr v2, JSValuePtr v3)
    183         {
    184             return (rawValue(v1) | rawValue(v2) | rawValue(v3)) & TagMask;
    185         }
    186 
    187236        static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2)
    188237        {
     
    193242        {
    194243            return rawValue(v1) & rawValue(v2) & TagTypeInteger;
    195         }
    196 
    197         static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    198         {
    199             ASSERT(areBothImmediateNumbers(v1, v2));
    200             return makeValue(rawValue(v1) & rawValue(v2));
    201         }
    202 
    203         static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    204         {
    205             ASSERT(areBothImmediateNumbers(v1, v2));
    206             return makeValue((rawValue(v1) ^ rawValue(v2)) | TagTypeInteger);
    207         }
    208 
    209         static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    210         {
    211             ASSERT(areBothImmediateNumbers(v1, v2));
    212             return makeValue(rawValue(v1) | rawValue(v2));
    213         }
    214 
    215         static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)
    216         {
    217             ASSERT(areBothImmediateNumbers(val, shift));
    218 #if USE(ALTERNATE_JSIMMEDIATE)
    219             return makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(rawValue(val)) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f))) | TagTypeInteger);
    220 #else
    221             return makeValue((rawValue(val) >> ((rawValue(shift) >> IntegerPayloadShift) & 0x1f)) | TagTypeInteger);
    222 #endif
    223         }
    224 
    225         static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)
    226         {
    227             // Number is non-negative and an operation involving two of these can't overflow.
    228             // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
    229             return (rawValue(v) & (TagTypeInteger + (signBit | (signBit >> 1)))) == TagTypeInteger;
    230         }
    231 
    232         static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    233         {
    234             ASSERT(canDoFastAdditiveOperations(v1));
    235             ASSERT(canDoFastAdditiveOperations(v2));
    236             return makeValue(rawValue(v1) + rawValue(v2) - TagTypeInteger);
    237         }
    238 
    239         static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
    240         {
    241             ASSERT(canDoFastAdditiveOperations(v1));
    242             ASSERT(canDoFastAdditiveOperations(v2));
    243             return makeValue(rawValue(v1) - rawValue(v2) + TagTypeInteger);
    244         }
    245 
    246         static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)
    247         {
    248             ASSERT(canDoFastAdditiveOperations(v));
    249             return makeValue(rawValue(v) + (1 << IntegerPayloadShift));
    250         }
    251 
    252         static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)
    253         {
    254             ASSERT(canDoFastAdditiveOperations(v));
    255             return makeValue(rawValue(v) - (1 << IntegerPayloadShift));
    256244        }
    257245
     
    484472    }
    485473
     474    inline JSValuePtr js0()
     475    {
     476        return JSImmediate::zeroImmediate();
     477    }
     478
    486479    inline JSValuePtr jsNull()
    487480    {
     
    497490    {
    498491        return JSImmediate::undefinedImmediate();
     492    }
     493
     494    inline JSValuePtr jsImpossibleValue()
     495    {
     496        return JSImmediate::impossibleValue();
    499497    }
    500498
     
    545543        if (getTruncatedInt32(i))
    546544            return i;
    547         bool ok;
    548         return toInt32SlowCase(exec, ok);
     545        bool ignored;
     546        return toInt32SlowCase(toNumber(exec), ignored);
    549547    }
    550548
     
    554552        if (getTruncatedUInt32(i))
    555553            return i;
    556         bool ok;
    557         return toUInt32SlowCase(exec, ok);
     554        bool ignored;
     555        return toUInt32SlowCase(toNumber(exec), ignored);
    558556    }
    559557
     
    583581            return i;
    584582        }
    585         return toInt32SlowCase(exec, ok);
     583        return toInt32SlowCase(toNumber(exec), ok);
    586584    }
    587585
     
    593591            return i;
    594592        }
    595         return toUInt32SlowCase(exec, ok);
    596     }
     593        return toUInt32SlowCase(toNumber(exec), ok);
     594    }
     595
     596    inline bool JSValuePtr::isCell() const
     597    {
     598        return !JSImmediate::isImmediate(asValue());
     599    }
     600
     601    inline bool JSValuePtr::isInt32Fast() const
     602    {
     603        return JSImmediate::isNumber(asValue());
     604    }
     605
     606    inline int32_t JSValuePtr::getInt32Fast() const
     607    {
     608        ASSERT(isInt32Fast());
     609        return JSImmediate::getTruncatedInt32(asValue());
     610    }
     611
     612    inline bool JSValuePtr::isUInt32Fast() const
     613    {
     614        return JSImmediate::isPositiveNumber(asValue());
     615    }
     616
     617    inline uint32_t JSValuePtr::getUInt32Fast() const
     618    {
     619        ASSERT(isUInt32Fast());
     620        return JSImmediate::getTruncatedUInt32(asValue());
     621    }
     622
     623    inline JSValuePtr JSValuePtr::makeInt32Fast(int32_t i)
     624    {
     625        return JSImmediate::from(i);
     626    }
     627
     628    inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2)
     629    {
     630        return JSImmediate::areBothImmediateNumbers(v1, v2);
     631    }
     632
     633    class JSFastMath {
     634    public:
     635        static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2)
     636        {
     637            return JSImmediate::areBothImmediateNumbers(v1, v2);
     638        }
     639
     640        static ALWAYS_INLINE JSValuePtr equal(JSValuePtr v1, JSValuePtr v2)
     641        {
     642            ASSERT(canDoFastBitwiseOperations(v1, v2));
     643            return jsBoolean(v1 == v2);
     644        }
     645
     646        static ALWAYS_INLINE JSValuePtr notEqual(JSValuePtr v1, JSValuePtr v2)
     647        {
     648            ASSERT(canDoFastBitwiseOperations(v1, v2));
     649            return jsBoolean(v1 != v2);
     650        }
     651
     652        static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
     653        {
     654            ASSERT(canDoFastBitwiseOperations(v1, v2));
     655            return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2));
     656        }
     657
     658        static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
     659        {
     660            ASSERT(canDoFastBitwiseOperations(v1, v2));
     661            return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeInteger);
     662        }
     663
     664        static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
     665        {
     666            ASSERT(canDoFastBitwiseOperations(v1, v2));
     667            return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2));
     668        }
     669
     670        static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2)
     671        {
     672            return JSImmediate::areBothImmediateNumbers(v1, v2);
     673        }
     674
     675        static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2)
     676        {
     677            return JSImmediate::areBothImmediateNumbers(v1, v2) && !JSImmediate::isNegative(v1);
     678        }
     679
     680        static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)
     681        {
     682            ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
     683#if USE(ALTERNATE_JSIMMEDIATE)
     684            return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeInteger);
     685#else
     686            return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeInteger);
     687#endif
     688        }
     689
     690        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)
     691        {
     692            // Number is non-negative and an operation involving two of these can't overflow.
     693            // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
     694            return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeInteger + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeInteger;
     695        }
     696
     697        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v1, JSValuePtr v2)
     698        {
     699            // Number is non-negative and an operation involving two of these can't overflow.
     700            // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
     701            return ((JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2)) & (JSImmediate::TagTypeInteger + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeInteger;
     702        }
     703
     704        static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
     705        {
     706            ASSERT(canDoFastAdditiveOperations(v1, v2));
     707            return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeInteger);
     708        }
     709
     710        static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
     711        {
     712            ASSERT(canDoFastAdditiveOperations(v1, v2));
     713            return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeInteger);
     714        }
     715
     716        static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)
     717        {
     718            ASSERT(canDoFastAdditiveOperations(v));
     719            return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift));
     720        }
     721
     722        static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)
     723        {
     724            ASSERT(canDoFastAdditiveOperations(v));
     725            return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift));
     726        }
     727    };
    597728
    598729} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSNumberCell.h

    r39769 r39851  
    108108    extern const double Inf;
    109109
    110     JSNumberCell* asNumberCell(JSValuePtr);
    111 
    112110    JSValuePtr jsNumberCell(JSGlobalData*, double);
    113111    JSValuePtr jsNaN(JSGlobalData*);
     
    115113    JSValuePtr jsNaN(ExecState*);
    116114
    117     inline JSNumberCell* asNumberCell(JSValuePtr value)
    118     {
    119         ASSERT(asCell(value)->isNumber());
    120         return static_cast<JSNumberCell*>(asCell(value));
     115    inline JSNumberCell* JSValuePtr::asNumberCell() const
     116    {
     117        ASSERT(isNumberCell());
     118        return static_cast<JSNumberCell*>(asCell());
    121119    }
    122120
     
    127125    }
    128126
    129     ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, short i)
    130     {
    131         JSValuePtr v = JSImmediate::from(i);
    132         return v ? v : jsNumberCell(exec, i);
    133     }
    134 
    135     ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned short i)
    136     {
    137         JSValuePtr v = JSImmediate::from(i);
    138         return v ? v : jsNumberCell(exec, i);
     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);
    139149    }
    140150
     
    233243    inline double JSValuePtr::uncheckedGetNumber() const
    234244    {
    235         ASSERT(JSImmediate::isImmediate(asValue()) || asCell()->isNumber());
    236         return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell(asValue())->value();
     245        ASSERT(isNumber());
     246        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asNumberCell()->value();
    237247    }
    238248
     
    241251        if (m_value >= -2147483648.0 && m_value < 2147483648.0)
    242252            return static_cast<int32_t>(m_value);
    243         bool scratch;
    244         return JSC::toInt32SlowCase(m_value, scratch);
     253        bool ignored;
     254        return toInt32SlowCase(m_value, ignored);
    245255    }
    246256
     
    249259        if (m_value >= 0.0 && m_value < 4294967296.0)
    250260            return static_cast<uint32_t>(m_value);
    251         bool scratch;
    252         return JSC::toUInt32SlowCase(m_value, scratch);
     261        bool ignored;
     262        return toUInt32SlowCase(m_value, ignored);
    253263    }
    254264
    255265    ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
    256266    {
    257         return JSImmediate::isNumber(asValue()) ? asValue() : jsNumber(exec, this->toNumber(exec));
     267        return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
     268    }
     269
     270    inline bool JSValuePtr::getNumber(double &result) const
     271    {
     272        if (isInt32Fast())
     273            result = getInt32Fast();
     274        else if (LIKELY(isNumberCell()))
     275            result = asNumberCell()->value();
     276        else {
     277            ASSERT(!isNumber());
     278            return false;
     279        }
     280        return true;
     281    }
     282
     283    inline bool JSValuePtr::numberToInt32(int32_t& arg)
     284    {
     285        if (isInt32Fast())
     286            arg = getInt32Fast();
     287        else if (LIKELY(isNumberCell()))
     288            arg = asNumberCell()->toInt32();
     289        else {
     290            ASSERT(!isNumber());
     291            return false;
     292        }
     293        return true;
     294    }
     295
     296    inline bool JSValuePtr::numberToUInt32(uint32_t& arg)
     297    {
     298        if (isUInt32Fast())
     299            arg = getUInt32Fast();
     300        else if (LIKELY(isNumberCell()))
     301            arg = asNumberCell()->toUInt32();
     302        else if (isInt32Fast()) {
     303            // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
     304            // on a negative value is equivalent to simple static_casting.
     305            bool ignored;
     306            arg = toUInt32SlowCase(getInt32Fast(), ignored);
     307        } else {
     308            ASSERT(!isNumber());
     309            return false;
     310        }
     311        return true;
    258312    }
    259313
  • trunk/JavaScriptCore/runtime/JSObject.h

    r39769 r39851  
    271271inline bool JSValuePtr::isObject(const ClassInfo* classInfo) const
    272272{
    273     return !JSImmediate::isImmediate(asValue()) && asCell()->isObject(classInfo);
     273    return isCell() && asCell()->isObject(classInfo);
    274274}
    275275
     
    474474inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
    475475{
    476     if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
     476    if (UNLIKELY(!isCell())) {
    477477        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
    478478        if (!prototype->getPropertySlot(exec, propertyName, slot))
     
    500500inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
    501501{
    502     if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
     502    if (UNLIKELY(!isCell())) {
    503503        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
    504504        if (!prototype->getPropertySlot(exec, propertyName, slot))
     
    520520inline void JSValuePtr::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
    521521{
    522     if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
     522    if (UNLIKELY(!isCell())) {
    523523        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
    524524        return;
     
    529529inline void JSValuePtr::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
    530530{
    531     if (UNLIKELY(JSImmediate::isImmediate(asValue()))) {
     531    if (UNLIKELY(!isCell())) {
    532532        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
    533533        return;
  • trunk/JavaScriptCore/runtime/JSValue.cpp

    r39769 r39851  
    3434double JSValuePtr::toInteger(ExecState* exec) const
    3535{
    36     int32_t i;
    37     if (getTruncatedInt32(i))
    38         return i;
     36    if (isInt32Fast())
     37        return getInt32Fast();
    3938    double d = toNumber(exec);
    4039    return isnan(d) ? 0.0 : trunc(d);
     
    4342double JSValuePtr::toIntegerPreserveNaN(ExecState* exec) const
    4443{
    45     int32_t i;
    46     if (getTruncatedInt32(i))
    47         return i;
     44    if (isInt32Fast())
     45        return getInt32Fast();
    4846    return trunc(toNumber(exec));
    4947}
     
    6967}
    7068
    71 int32_t JSValuePtr::toInt32SlowCase(ExecState* exec, bool& ok) const
    72 {
    73     return JSC::toInt32SlowCase(toNumber(exec), ok);
    74 }
    75 
    7669uint32_t toUInt32SlowCase(double d, bool& ok)
    7770{
     
    9285}
    9386
    94 uint32_t JSValuePtr::toUInt32SlowCase(ExecState* exec, bool& ok) const
    95 {
    96     return JSC::toUInt32SlowCase(toNumber(exec), ok);
    97 }
    98 
    9987} // namespace JSC
  • trunk/JavaScriptCore/runtime/JSValue.h

    r39769 r39851  
    3434    class Identifier;
    3535    class JSCell;
     36    class JSNumberCell;
    3637    class JSObject;
    3738    class JSString;
     
    121122        bool getBoolean(bool&) const;
    122123        bool getBoolean() const; // false if not a boolean
    123         double getNumber() const; // NaN if not a number
     124        bool getNumber(double&) const;
    124125        double uncheckedGetNumber() const;
    125126        bool getString(UString&) const;
     
    149150
    150151        // Integer conversions.
     152        // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
    151153        double toInteger(ExecState*) const;
    152154        double toIntegerPreserveNaN(ExecState*) const;
    153155        int32_t toInt32(ExecState*) const;
    154156        int32_t toInt32(ExecState*, bool& ok) const;
     157        bool numberToInt32(int32_t& arg);
    155158        uint32_t toUInt32(ExecState*) const;
    156159        uint32_t toUInt32(ExecState*, bool& ok) const;
    157 
    158         // Floating point conversions.
     160        bool numberToUInt32(uint32_t& arg);
     161
     162        // Fast integer operations; these values return results where the value is trivially available
     163        // in a convenient form, for use in optimizations.  No assumptions should be made based on the
     164        // results of these operations, for example !isInt32Fast() does not necessarily indicate the
     165        // result of getNumber will not be 0.
     166        bool isInt32Fast() const;
     167        int32_t getInt32Fast() const;
     168        bool isUInt32Fast() const;
     169        uint32_t getUInt32Fast() const;
     170        static JSValuePtr makeInt32Fast(int32_t);
     171        static bool areBothInt32Fast(JSValuePtr, JSValuePtr);
     172
     173        // Floating point conversions (this is a convenience method for webcore;
     174        // signle precision float is not a representation used in JS or JSC).
    159175        float toFloat(ExecState* exec) const { return static_cast<float>(toNumber(exec)); }
    160176
     
    176192        JSString* toThisJSString(ExecState*);
    177193
    178         JSValuePtr getJSNumber(); // 0 if this is not a JSNumber or number object
    179 
     194        static bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
     195        static bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
     196        static bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
     197        static bool strictEqual(JSValuePtr v1, JSValuePtr v2);
     198        static bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2);
     199        static bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2);
     200
     201        JSValuePtr getJSNumber(); // noValue() if this is not a JSNumber or number object
     202
     203        bool isCell() const;
    180204        JSCell* asCell() const;
    181205
     
    183207        inline const JSValuePtr asValue() const { return *this; }
    184208
    185         int32_t toInt32SlowCase(ExecState*, bool& ok) const;
    186         uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
     209        bool isNumberCell() const;
     210        JSNumberCell* asNumberCell() const;
    187211
    188212        JSCell* m_ptr;
  • trunk/JavaScriptCore/runtime/Operations.cpp

    r39670 r39851  
    3636namespace JSC {
    3737
    38 // ECMA 11.9.3
    39 bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
    40 {
    41     if (JSImmediate::areBothImmediateNumbers(v1, v2))
    42         return v1 == v2;
    43 
    44     return equalSlowCaseInline(exec, v1, v2);
    45 }
    46 
    47 bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
     38bool JSValuePtr::equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
    4839{
    4940    return equalSlowCaseInline(exec, v1, v2);
    5041}
    5142
    52 bool strictEqual(JSValuePtr v1, JSValuePtr v2)
    53 {
    54     if (JSImmediate::areBothImmediate(v1, v2))
    55         return v1 == v2;
    56 
    57     if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != JSImmediate::from(0)) & (v2 != JSImmediate::from(0)))
    58         return false;
    59 
    60     return strictEqualSlowCaseInline(v1, v2);
    61 }
    62 
    63 bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2)
     43bool JSValuePtr::strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2)
    6444{
    6545    return strictEqualSlowCaseInline(v1, v2);
  • trunk/JavaScriptCore/runtime/Operations.h

    r39670 r39851  
    2929namespace JSC {
    3030
    31   // ECMA 11.9.3
    32   bool equal(ExecState*, JSValuePtr, JSValuePtr);
    33   bool equalSlowCase(ExecState*, JSValuePtr, JSValuePtr);
     31    // ECMA 11.9.3
     32    inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
     33    {
     34        if (JSImmediate::areBothImmediateNumbers(v1, v2))
     35            return v1 == v2;
    3436
    35   ALWAYS_INLINE bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
    36   {
    37       ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2));
     37        return equalSlowCase(exec, v1, v2);
     38    }
    3839
    39       do {
    40           if (v1->isNumber() && v2->isNumber())
    41               return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
     40    ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
     41    {
     42        ASSERT(!JSImmediate::areBothImmediateNumbers(v1, v2));
    4243
    43           bool s1 = v1->isString();
    44           bool s2 = v2->isString();
    45           if (s1 && s2)
    46               return asString(v1)->value() == asString(v2)->value();
     44        do {
     45            if (v1->isNumber() && v2->isNumber())
     46                return v1->uncheckedGetNumber() == v2->uncheckedGetNumber();
    4747
    48           if (v1->isUndefinedOrNull()) {
    49               if (v2->isUndefinedOrNull())
    50                   return true;
    51               if (JSImmediate::isImmediate(v2))
    52                   return false;
    53               return v2->asCell()->structure()->typeInfo().masqueradesAsUndefined();
    54           }
     48            bool s1 = v1->isString();
     49            bool s2 = v2->isString();
     50            if (s1 && s2)
     51                return asString(v1)->value() == asString(v2)->value();
    5552
    56           if (v2->isUndefinedOrNull()) {
    57               if (JSImmediate::isImmediate(v1))
    58                   return false;
    59               return v1->asCell()->structure()->typeInfo().masqueradesAsUndefined();
    60           }
     53            if (v1->isUndefinedOrNull()) {
     54                if (v2->isUndefinedOrNull())
     55                    return true;
     56                if (JSImmediate::isImmediate(v2))
     57                    return false;
     58                return v2->asCell()->structure()->typeInfo().masqueradesAsUndefined();
     59            }
    6160
    62           if (v1->isObject()) {
    63               if (v2->isObject())
    64                   return v1 == v2;
    65               JSValuePtr p1 = v1->toPrimitive(exec);
    66               if (exec->hadException())
    67                   return false;
    68               v1 = p1;
    69               if (JSImmediate::areBothImmediateNumbers(v1, v2))
    70                   return v1 == v2;
    71               continue;
    72           }
     61            if (v2->isUndefinedOrNull()) {
     62                if (JSImmediate::isImmediate(v1))
     63                    return false;
     64                return v1->asCell()->structure()->typeInfo().masqueradesAsUndefined();
     65            }
    7366
    74           if (v2->isObject()) {
    75               JSValuePtr p2 = v2->toPrimitive(exec);
    76               if (exec->hadException())
    77                   return false;
    78               v2 = p2;
    79               if (JSImmediate::areBothImmediateNumbers(v1, v2))
    80                   return v1 == v2;
    81               continue;
    82           }
     67            if (v1->isObject()) {
     68                if (v2->isObject())
     69                    return v1 == v2;
     70                JSValuePtr p1 = v1->toPrimitive(exec);
     71                if (exec->hadException())
     72                    return false;
     73                v1 = p1;
     74                if (JSImmediate::areBothImmediateNumbers(v1, v2))
     75                    return v1 == v2;
     76                continue;
     77            }
    8378
    84           if (s1 || s2) {
    85               double d1 = v1->toNumber(exec);
    86               double d2 = v2->toNumber(exec);
    87               return d1 == d2;
    88           }
     79            if (v2->isObject()) {
     80                JSValuePtr p2 = v2->toPrimitive(exec);
     81                if (exec->hadException())
     82                    return false;
     83                v2 = p2;
     84                if (JSImmediate::areBothImmediateNumbers(v1, v2))
     85                    return v1 == v2;
     86                continue;
     87            }
    8988
    90           if (v1->isBoolean()) {
    91               if (v2->isNumber())
    92                   return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber();
    93           } else if (v2->isBoolean()) {
    94               if (v1->isNumber())
    95                   return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean());
    96           }
     89            if (s1 || s2) {
     90                double d1 = v1->toNumber(exec);
     91                double d2 = v2->toNumber(exec);
     92                return d1 == d2;
     93            }
    9794
    98           return v1 == v2;
    99       } while (true);
    100   }
     95            if (v1->isBoolean()) {
     96                if (v2->isNumber())
     97                    return static_cast<double>(v1->getBoolean()) == v2->uncheckedGetNumber();
     98            } else if (v2->isBoolean()) {
     99                if (v1->isNumber())
     100                    return v1->uncheckedGetNumber() == static_cast<double>(v2->getBoolean());
     101            }
    101102
     103            return v1 == v2;
     104        } while (true);
     105    }
    102106
    103   bool strictEqual(JSValuePtr, JSValuePtr);
    104   bool strictEqualSlowCase(JSValuePtr, JSValuePtr);
     107    // ECMA 11.9.3
     108    inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2)
     109    {
     110        if (JSImmediate::areBothImmediate(v1, v2))
     111            return v1 == v2;
    105112
    106   inline bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2)
    107   {
    108       ASSERT(!JSImmediate::areBothImmediate(v1, v2));
    109      
    110       if (JSImmediate::isEitherImmediate(v1, v2)) {
    111           ASSERT(v1 == JSImmediate::zeroImmediate() || v2 == JSImmediate::zeroImmediate());
    112           ASSERT(v1 != v2);
     113        if (JSImmediate::isEitherImmediate(v1, v2) & (v1 != js0()) & (v2 != js0()))
     114            return false;
    113115
    114           // The reason we can't just return false here is that 0 === -0,
    115           // and while the former is an immediate number, the latter is not.
    116           if (v1 == JSImmediate::zeroImmediate())
    117               return asCell(v2)->isNumber() && asNumberCell(v2)->value() == 0;
    118           return asCell(v1)->isNumber() && asNumberCell(v1)->value() == 0;
    119       }
    120      
    121       if (asCell(v1)->isNumber()) {
    122           return asCell(v2)->isNumber()
    123               && asNumberCell(v1)->value() == asNumberCell(v2)->value();
    124       }
     116        return strictEqualSlowCase(v1, v2);
     117    }
    125118
    126       if (asCell(v1)->isString()) {
    127           return asCell(v2)->isString()
    128               && asString(v1)->value() == asString(v2)->value();
    129       }
     119    ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2)
     120    {
     121        ASSERT(!JSImmediate::areBothImmediate(v1, v2));
    130122
    131       return v1 == v2;
    132   }
     123        if (JSImmediate::isEitherImmediate(v1, v2)) {
     124            ASSERT(v1 == js0() || v2 == js0());
     125            ASSERT(v1 != v2);
    133126
    134   JSValuePtr throwOutOfMemoryError(ExecState*);
     127            // The reason we can't just return false here is that 0 === -0,
     128            // and while the former is an immediate number, the latter is not.
     129            if (v1 == js0())
     130                return v2->asCell()->isNumber() && v2->asNumberCell()->value() == 0;
     131            return v1->asCell()->isNumber() && v1->asNumberCell()->value() == 0;
     132        }
     133
     134        if (v1->asCell()->isNumber()) {
     135            return v2->asCell()->isNumber()
     136                && v1->asNumberCell()->value() == v2->asNumberCell()->value();
     137        }
     138
     139        if (v1->asCell()->isString()) {
     140            return v2->asCell()->isString()
     141                && asString(v1)->value() == asString(v2)->value();
     142        }
     143
     144        return v1 == v2;
     145    }
     146
     147    JSValuePtr throwOutOfMemoryError(ExecState*);
     148
    135149}
    136 
    137150#endif
  • trunk/JavaScriptCore/runtime/Protect.h

    r39670 r39851  
    5252    inline void gcProtect(JSValuePtr value)
    5353    {
    54         if (!value || JSImmediate::isImmediate(value))
    55             return;
    56         gcProtect(asCell(value));
     54        if (value && value->isCell())
     55            gcProtect(asCell(value));
    5756    }
    5857
    5958    inline void gcUnprotect(JSValuePtr value)
    6059    {
    61         if (!value || JSImmediate::isImmediate(value))
    62             return;
    63         gcUnprotect(asCell(value));
     60        if (value && value->isCell())
     61            gcUnprotect(asCell(value));
    6462    }
    6563
  • trunk/JavaScriptCore/runtime/StringPrototype.cpp

    r39670 r39851  
    329329    unsigned len = s.size();
    330330    JSValuePtr a0 = args.at(exec, 0);
    331     if (JSImmediate::isNumber(a0)) {
    332         uint32_t i;
    333         if (JSImmediate::getUInt32(a0, i) && i < len)
     331    if (a0->isUInt32Fast()) {
     332        uint32_t i = a0->getUInt32Fast();
     333        if (i < len)
    334334            return jsSingleCharacterSubstring(exec, s, i);
    335335        return jsEmptyString(exec);
     
    346346    unsigned len = s.size();
    347347    JSValuePtr a0 = args.at(exec, 0);
    348     if (JSImmediate::isNumber(a0)) {
    349         uint32_t i;
    350         if (JSImmediate::getUInt32(a0, i) && i < len)
     348    if (a0->isUInt32Fast()) {
     349        uint32_t i = a0->getUInt32Fast();
     350        if (i < len)
    351351            return jsNumber(exec, s.data()[i]);
    352352        return jsNaN(exec);
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r39670 r39851  
    541541
    542542    JSValuePtr prototype = storedPrototype();
    543     if (JSImmediate::isImmediate(prototype))
     543    if (!prototype->isCell())
    544544        return 0;
    545545
Note: See TracChangeset for help on using the changeset viewer.