Changeset 34964 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Jul 2, 2008, 5:47:00 PM (17 years ago)
Author:
[email protected]
Message:

2008-07-02 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.

Optimized a[n] get for cases where a is an array or a string, and a[n]
put for cases where a is an array.


SunSpider says 9.0% faster.

Location:
trunk/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r34962 r34964  
     12008-07-02  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Optimized a[n] get for cases where a is an array or a string, and a[n]
     6        put for cases where a is an array.
     7       
     8        SunSpider says 9.0% faster.
     9
    1102008-07-02  Kevin McCullough  <[email protected]>
    211
  • trunk/JavaScriptCore/VM/Machine.cpp

    r34947 r34964  
    4646#include "RegExpPrototype.h"
    4747#include "Register.h"
     48#include "collector.h"
    4849#include "debugger.h"
    4950#include "operations.h"
     
    476477{
    477478    privateExecute(InitializeAndReturn);
     479   
     480    // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
     481    void* storage = fastMalloc(sizeof(CollectorBlock));
     482
     483    JSArray* jsArray = new (storage) JSArray(jsNull(), 0);
     484    m_jsArrayVptr = jsArray->vptr();
     485    jsArray->~JSCell();
     486
     487    JSString* jsString = new (storage) JSString("");
     488    m_jsStringVptr = jsString->vptr();
     489    jsString->~JSCell();
     490   
     491    fastFree(storage);
    478492}
    479493
     
    18351849
    18361850        bool isUInt32 = JSImmediate::getUInt32(subscript, i);
    1837         if (LIKELY(isUInt32))
    1838             result = baseValue->get(exec, i);
    1839         else {
     1851        if (LIKELY(isUInt32)) {
     1852            if (isJSArray(baseValue)) {
     1853                JSArray* jsArray = static_cast<JSArray*>(baseValue);
     1854                if (jsArray->canGetIndex(i))
     1855                    result = jsArray->getIndex(i);
     1856                else
     1857                    result = jsArray->JSArray::get(exec, i);
     1858            } else if (isJSString(baseValue) && static_cast<JSString*>(baseValue)->canGetIndex(i))
     1859                result = static_cast<JSString*>(baseValue)->getIndex(exec, i);
     1860            else
     1861                result = baseValue->get(exec, i);
     1862        } else {
    18401863            Identifier property(exec, subscript->toString(exec));
    18411864            result = baseValue->get(exec, property);
     
    18681891
    18691892        bool isUInt32 = JSImmediate::getUInt32(subscript, i);
    1870         if (LIKELY(isUInt32))
    1871             baseValue->put(exec, i, r[value].u.jsValue);
    1872         else {
     1893        if (LIKELY(isUInt32)) {
     1894            if (isJSArray(baseValue)) {
     1895                JSArray* jsArray = static_cast<JSArray*>(baseValue);
     1896                if (jsArray->canSetIndex(i))
     1897                    jsArray->setIndex(i, r[value].u.jsValue);
     1898                else
     1899                    jsArray->JSArray::put(exec, i, r[value].u.jsValue);
     1900            } else
     1901                baseValue->put(exec, i, r[value].u.jsValue);
     1902        } else {
    18731903            Identifier property(exec, subscript->toString(exec));
    18741904            if (!exec->hadException()) // Don't put to an object if toString threw an exception.
  • trunk/JavaScriptCore/VM/Machine.h

    r34907 r34964  
    3030#define Machine_h
    3131
     32#include "JSCell.h"
     33#include "JSValue.h"
    3234#include "Opcode.h"
    3335#include "RegisterFile.h"
     
    141143        void resetTimeoutCheck();
    142144
     145        bool isJSArray(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsArrayVptr; }
     146        bool isJSString(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsStringVptr; }
     147       
    143148        int m_reentryDepth;
    144149        unsigned m_timeoutTime;
     
    149154
    150155        RegisterFile m_registerFile;
     156       
     157        void* m_jsArrayVptr;
     158        void* m_jsStringVptr;
    151159
    152160#if HAVE(COMPUTED_GOTO)
  • trunk/JavaScriptCore/kjs/JSArray.cpp

    r34868 r34964  
    3535namespace KJS {
    3636
    37 typedef HashMap<unsigned, JSValue*> SparseArrayValueMap;
    38 
    39 struct ArrayStorage {
    40     unsigned m_vectorLength;
    41     unsigned m_numValuesInVector;
    42     SparseArrayValueMap* m_sparseValueMap;
    43     void* lazyCreationData; // An JSArray subclass can use this to fill the vector lazily.
    44     JSValue* m_vector[1];
    45 };
    46 
    4737// 0xFFFFFFFF is a bit weird -- is not an array index even though it's an integer.
    4838static const unsigned maxArrayIndex = 0xFFFFFFFEU;
     
    8272#endif
    8373
    84 JSArray::JSArray(JSObject* prototype, unsigned initialLength)
     74JSArray::JSArray(JSValue* prototype, unsigned initialLength)
    8575    : JSObject(prototype)
    8676{
  • trunk/JavaScriptCore/kjs/JSArray.h

    r34868 r34964  
    2727namespace KJS {
    2828
    29   struct ArrayStorage;
     29  typedef HashMap<unsigned, JSValue*> SparseArrayValueMap;
     30
     31  struct ArrayStorage {
     32      unsigned m_vectorLength;
     33      unsigned m_numValuesInVector;
     34      SparseArrayValueMap* m_sparseValueMap;
     35      void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
     36      JSValue* m_vector[1];
     37  };
    3038
    3139  class JSArray : public JSObject {
    3240  public:
    33     JSArray(JSObject* prototype, unsigned initialLength);
     41    JSArray(JSValue* prototype, unsigned initialLength);
    3442    JSArray(JSObject* prototype, const ArgList& initialValues);
    3543    virtual ~JSArray();
     
    4654    void sort(ExecState*);
    4755    void sort(ExecState*, JSValue* compareFunction, CallType, const CallData&);
     56
     57    bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
     58    JSValue* getIndex(unsigned i)
     59    {
     60        ASSERT(canGetIndex(i));
     61        return m_storage->m_vector[i];
     62    }
     63
     64    bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; }
     65    JSValue* setIndex(unsigned i, JSValue* v)
     66    {
     67        ASSERT(canSetIndex(i));
     68        return m_storage->m_vector[i] = v;
     69    }
    4870
    4971  protected:
  • trunk/JavaScriptCore/kjs/JSCell.h

    r34921 r34964  
    3737    friend class JSNumberCell;
    3838    friend class JSString;
     39    friend class Machine;
    3940private:
    4041    JSCell();
     
    7576    // Garbage collection.
    7677    void* operator new(size_t, ExecState*);
     78    void* operator new(size_t, void* placementNewDestination) { return placementNewDestination; }
    7779    virtual void mark();
    7880    bool marked() const;
     
    8991    virtual JSString* toThisJSString(ExecState*);
    9092    virtual JSValue* getJSNumber();
     93    void* vptr() { return *reinterpret_cast<void**>(this); }
    9194
    9295private:
  • trunk/JavaScriptCore/kjs/JSString.h

    r34921 r34964  
    4343    bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
    4444    bool getStringPropertySlot(unsigned propertyName, PropertySlot&);
     45
     46    bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
     47    JSValue* getIndex(ExecState* exec, unsigned i)
     48    {
     49        ASSERT(canGetIndex(i));
     50        return new (exec) JSString(m_value.substr(i, 1));
     51    }
    4552
    4653  private:
  • trunk/JavaScriptCore/kjs/JSValue.h

    r34921 r34964  
    5353    friend class JSCell; // so it can derive from this class
    5454    friend class Heap; // so it can call asCell()
     55    friend class Machine; // so it can call asCell()
    5556private:
    5657    JSValue();
Note: See TracChangeset for help on using the changeset viewer.