Changeset 27448 in webkit


Ignore:
Timestamp:
Nov 5, 2007, 1:27:15 PM (18 years ago)
Author:
ggaren
Message:

JavaScriptCore:

Reviewed by Darin Adler.


http://bugs.webkit.org/show_bug.cgi?id=15835

Switched List implementation from a custom heap allocator to an inline
Vector, for a disappointing .5% SunSpider speedup.


Also renamed List::slice to List::getSlice because "get" is the
conventional prefix for functions returning a value through an out
parameter.

  • kjs/array_object.cpp: (KJS::ArrayProtoFunc::callAsFunction): Removed some redundant function calls and memory accesses.
  • kjs/bool_object.cpp: (BooleanObjectImp::construct): Removed questionable use of iterator.
  • kjs/list.cpp:
  • kjs/list.h: New List class, implemented in terms of Vector. Two interesting differences:
    1. The inline capacity is 8, not 5. Many of the Lists constructed during a SunSpider run are larger than 5; almost none are larger than 8.
  1. The growth factor is 4, not 2. Since we can guarantee that Lists aren't long-lived, we can grow them more aggressively, to avoid excessive copying.
  • kjs/regexp_object.cpp: (RegExpObjectImp::construct): Removed redundant function calls.
  • kjs/string_object.cpp: (KJS::StringObjectImp::construct): Removed questionable use of iterator.
  • wtf/Vector.h: (WTF::::uncheckedAppend): Added a fast, unchecked version of append.

WebCore:

Reviewed by Darin Adler.


http://bugs.webkit.org/show_bug.cgi?id=15835

Small adaptations to new KJS::List class.

  • bindings/js/kjs_window.cpp: (KJS::WindowFunc::callAsFunction): (KJS::ScheduledAction::ScheduledAction):

WebKit:

Reviewed by Darin Adler.


http://bugs.webkit.org/show_bug.cgi?id=15835

Small adaptations to new KJS::List class.

  • ForwardingHeaders/kjs/value.h: Added.
Location:
trunk
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r27447 r27448  
     12007-11-05  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Darin Adler.
     4       
     5        http://bugs.webkit.org/show_bug.cgi?id=15835
     6
     7        Switched List implementation from a custom heap allocator to an inline
     8        Vector, for a disappointing .5% SunSpider speedup.
     9       
     10        Also renamed List::slice to List::getSlice because "get" is the
     11        conventional prefix for functions returning a value through an out
     12        parameter.
     13
     14        * kjs/array_object.cpp:
     15        (KJS::ArrayProtoFunc::callAsFunction): Removed some redundant function
     16        calls and memory accesses.
     17
     18        * kjs/bool_object.cpp:
     19        (BooleanObjectImp::construct): Removed questionable use of iterator.
     20
     21        * kjs/list.cpp:
     22        * kjs/list.h: New List class, implemented in terms of Vector. Two
     23        interesting differences:
     24            1. The inline capacity is 8, not 5. Many of the Lists constructed
     25            during a SunSpider run are larger than 5; almost none are larger
     26            than 8.
     27
     28            2. The growth factor is 4, not 2. Since we can guarantee that Lists
     29            aren't long-lived, we can grow them more aggressively, to avoid
     30            excessive copying.
     31
     32        * kjs/regexp_object.cpp:
     33        (RegExpObjectImp::construct): Removed redundant function calls.
     34
     35        * kjs/string_object.cpp:
     36        (KJS::StringObjectImp::construct): Removed questionable use of iterator.
     37
     38        * wtf/Vector.h:
     39        (WTF::::uncheckedAppend): Added a fast, unchecked version of append.
     40
    1412007-11-05  Mark Rowe  <[email protected]>
    242
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r27419 r27448  
    124124__ZN3KJS11Interpreter8evaluateERKNS_7UStringEiS3_PNS_7JSValueE
    125125__ZN3KJS11InterpreterC1EPNS_14JSGlobalObjectE
     126__ZN3KJS11InterpreterC1EPNS_14JSGlobalObjectE
    126127__ZN3KJS11InterpreterC1Ev
    127128__ZN3KJS11InterpreterC2EPNS_14JSGlobalObjectE
     
    158159__ZN3KJS19InternalFunctionImp4infoE
    159160__ZN3KJS19InternalFunctionImpC2EPNS_17FunctionPrototypeERKNS_10IdentifierE
    160 __ZN3KJS4List6appendEPNS_7JSValueE
    161 __ZN3KJS4List7releaseEv
    162 __ZN3KJS4ListC1Ev
     161__ZN3KJS4List15expandAndAppendEPNS_7JSValueE
     162__ZN3KJS4List7markSetEv
    163163__ZN3KJS6JSCell9getObjectEv
    164164__ZN3KJS6JSCellnwEm
     
    242242__ZNK3KJS19InternalFunctionImp14implementsCallEv
    243243__ZNK3KJS19InternalFunctionImp21implementsHasInstanceEv
    244 __ZNK3KJS4List2atEi
    245 __ZNK3KJS4List5sliceEiRS0_
     244__ZNK3KJS4List8getSliceEiRS0_
    246245__ZNK3KJS6JSCell17getTruncatedInt32ERi
     246__ZNK3KJS6JSCell17getTruncatedInt32ERi
     247__ZNK3KJS6JSCell18getTruncatedUInt32ERj
    247248__ZNK3KJS6JSCell18getTruncatedUInt32ERj
    248249__ZNK3KJS6JSCell9getNumberERd
     
    266267__ZNK3KJS8JSObject12defaultValueEPNS_9ExecStateENS_6JSTypeE
    267268__ZNK3KJS8JSObject14implementsCallEv
     269__ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
    268270__ZNK3KJS8JSObject18getPrimitiveNumberEPNS_9ExecStateERd
    269271__ZNK3KJS8JSObject19implementsConstructEv
  • trunk/JavaScriptCore/kjs/array_instance.cpp

    r27413 r27448  
    9494    storage->m_sparseValueMap = 0;
    9595
    96     ListIterator it = list.begin();
    97     for (unsigned i = 0; i < length; ++i)
    98         storage->m_vector[i] = it++;
     96    size_t i = 0;
     97    List::const_iterator end = list.end();
     98    for (List::const_iterator it = list.begin(); it != end; ++it, ++i)
     99        storage->m_vector[i] = *it;
    99100
    100101    m_storage = storage;
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r27413 r27448  
    165165    JSValue *curArg = thisObj;
    166166    JSObject *curObj = static_cast<JSObject *>(thisObj);
    167     ListIterator it = args.begin();
     167    List::const_iterator it = args.begin();
     168    List::const_iterator end = args.end();
    168169    for (;;) {
    169170      if (curArg->isObject() &&
     
    183184        n++;
    184185      }
    185       if (it == args.end())
     186      if (it == end)
    186187        break;
    187188      curArg = *it;
    188       curObj = static_cast<JSObject *>(it++); // may be 0
     189      curObj = static_cast<JSObject*>(curArg); // may be 0
     190      ++it;
    189191    }
    190192    arr->put(exec, exec->propertyNames().length, jsNumber(n), DontEnum | DontDelete);
  • trunk/JavaScriptCore/kjs/bool_object.cpp

    r27413 r27448  
    106106  bool b;
    107107  if (args.size() > 0)
    108     b = args.begin()->toBoolean(exec);
     108    b = args[0]->toBoolean(exec);
    109109  else
    110110    b = false;
  • trunk/JavaScriptCore/kjs/function.cpp

    r27413 r27448  
    274274 
    275275  int i = 0;
    276   ListIterator iterator = args.begin();
    277   for (; iterator != args.end(); i++, iterator++)
     276  List::const_iterator end = args.end();
     277  for (List::const_iterator it = args.begin(); it != end; ++i, ++it)
    278278    _map[i] = func->getParameterName(i); // null if there is no corresponding parameter
    279279}
     
    339339 
    340340  int i = 0;
    341   ListIterator iterator = args.begin();
    342   for (; iterator != args.end(); i++, iterator++) {
     341  List::const_iterator end = args.end();
     342  for (List::const_iterator it = args.begin(); it != end; ++it, ++i) {
    343343    if (!indexToNameMap.isMapped(Identifier::from(i))) {
    344       JSObject::put(exec, Identifier::from(i), *iterator, DontEnum);
     344      JSObject::put(exec, Identifier::from(i), *it, DontEnum);
    345345    }
    346346  }
  • trunk/JavaScriptCore/kjs/function_object.cpp

    r27373 r27448  
    139139
    140140    List argsTail;
    141     args.slice(1, argsTail);
     141    args.getSlice(1, argsTail);
    142142    result = func->call(exec, callThis, argsTail);
    143143    }
  • trunk/JavaScriptCore/kjs/list.cpp

    r27373 r27448  
    2222#include "list.h"
    2323
    24 #include "internal.h"
    25 #include <algorithm>
    26 
    27 #define DUMP_STATISTICS 0
    28 
    29 using std::min;
    30 
    3124namespace KJS {
    3225
    33 // tunable parameters
    34 const int poolSize = 512;
    35 const int inlineValuesSize = 5;
    36 
    37 enum ListImpState { unusedInPool = 0, usedInPool, usedOnHeap, immortal };
    38 
    39 struct ListImp : ListImpBase
     26void List::getSlice(int startIndex, List& result) const
    4027{
    41     ListImpState state;
    42     int capacity;
    43     JSValue** overflow;
    44 
    45     union {
    46         JSValue *values[inlineValuesSize];
    47         ListImp *nextInFreeList;
    48     };
    49 
    50 #if DUMP_STATISTICS
    51     int sizeHighWaterMark;
    52 #endif
    53 
    54     void markValues();
    55 };
    56 
    57 struct HeapListImp : ListImp
    58 {
    59     HeapListImp *nextInHeapList;
    60     HeapListImp *prevInHeapList;
    61 };
    62 
    63 static ListImp pool[poolSize];
    64 static ListImp *poolFreeList;
    65 static HeapListImp *heapList;
    66 static int poolUsed;
    67 
    68 #if DUMP_STATISTICS
    69 
    70 static int numLists;
    71 static int numListsHighWaterMark;
    72 
    73 static int listSizeHighWaterMark;
    74 
    75 static int numListsDestroyed;
    76 static int numListsBiggerThan[17];
    77 
    78 struct ListStatisticsExitLogger { ~ListStatisticsExitLogger(); };
    79 
    80 static ListStatisticsExitLogger logger;
    81 
    82 ListStatisticsExitLogger::~ListStatisticsExitLogger()
    83 {
    84     printf("\nKJS::List statistics:\n\n");
    85     printf("%d lists were allocated\n", numLists);
    86     printf("%d lists was the high water mark\n", numListsHighWaterMark);
    87     printf("largest list had %d elements\n", listSizeHighWaterMark);
    88     if (numListsDestroyed) {
    89         putc('\n', stdout);
    90         for (int i = 0; i < 17; i++) {
    91             printf("%.1f%% of the lists (%d) had more than %d element%s\n",
    92                 100.0 * numListsBiggerThan[i] / numListsDestroyed,
    93                 numListsBiggerThan[i],
    94                 i, i == 1 ? "" : "s");
    95         }
    96         putc('\n', stdout);
    97     }
     28    const_iterator start = min(begin() + startIndex, end());
     29    result.m_vector.appendRange(start, end());
    9830}
    9931
    100 #endif
     32const List& List::empty()
     33{
     34    static const List staticList;
     35    return staticList;
     36}
    10137
    102 inline void ListImp::markValues()
     38List::ListSet& List::markSet()
    10339{
    104     int inlineSize = min(size, inlineValuesSize);
    105     for (int i = 0; i != inlineSize; ++i) {
    106         if (!values[i]->marked()) {
    107             values[i]->mark();
    108         }
    109     }
     40    static ListSet staticMarkSet;
     41    return staticMarkSet;
     42}
    11043
    111     int overflowSize = size - inlineSize;
    112     for (int i = 0; i != overflowSize; ++i) {
    113         if (!overflow[i]->marked()) {
    114             overflow[i]->mark();
     44void List::markProtectedListsSlowCase()
     45{
     46    ListSet::iterator end = markSet().end();
     47    for (ListSet::iterator it = markSet().begin(); it != end; ++it) {
     48        List* list = *it;
     49
     50        iterator end2 = list->end();
     51        for (iterator it2 = list->begin(); it2 != end2; ++it2) {
     52            JSValue* v = *it2;
     53            if (!v->marked())
     54                v->mark();
    11555        }
    11656    }
    11757}
    11858
    119 void List::markProtectedLists()
     59void List::expandAndAppend(JSValue* v)
    12060{
    121     int seen = 0;
    122     int used = poolUsed;
    123 
    124     for (int i = 0; i < poolSize && seen < used; i++) {
    125         if (pool[i].state == usedInPool) {
    126             seen++;
    127             if (pool[i].valueRefCount > 0) {
    128                 pool[i].markValues();
    129             }
    130         }
     61    ASSERT(m_vector.size() == m_vector.capacity());
     62   
     63    // 4x growth would be excessive for a normal vector, but it's OK for Lists
     64    // because they're short-lived.
     65    m_vector.reserveCapacity(m_vector.capacity() * 4);
     66   
     67    // As long as our size stays within our Vector's inline
     68    // capacity, all our values are allocated on the stack, and
     69    // therefore don't need explicit marking. Once our size exceeds
     70    // our Vector's inline capacity, though, our values move to the
     71    // heap, where they do need explicit marking.
     72    if (!m_isInMarkSet) {
     73        markSet().add(this);
     74        m_isInMarkSet = true;
    13175    }
    13276
    133     for (HeapListImp *l = heapList; l; l = l->nextInHeapList) {
    134         if (l->valueRefCount > 0) {
    135             l->markValues();
    136         }
    137     }
    138 }
    139 
    140 
    141 static inline ListImp *allocateListImp()
    142 {
    143     ASSERT(JSLock::lockCount() > 0);
    144    
    145     // Find a free one in the pool.
    146     if (poolUsed < poolSize) {
    147         ListImp *imp = poolFreeList ? poolFreeList : &pool[0];
    148         poolFreeList = imp->nextInFreeList ? imp->nextInFreeList : imp + 1;
    149         imp->state = usedInPool;
    150         poolUsed++;
    151         return imp;
    152     }
    153    
    154     HeapListImp *imp = new HeapListImp;
    155     imp->state = usedOnHeap;
    156     // link into heap list
    157     if (heapList) {
    158         heapList->prevInHeapList = imp;
    159     }
    160     imp->nextInHeapList = heapList;
    161     imp->prevInHeapList = NULL;
    162     heapList = imp;
    163 
    164     return imp;
    165 }
    166 
    167 List::List() : _impBase(allocateListImp())
    168 {
    169     ListImp *imp = static_cast<ListImp *>(_impBase);
    170     imp->size = 0;
    171     imp->refCount = 1;
    172     imp->valueRefCount = 1;
    173     imp->capacity = 0;
    174     imp->overflow = 0;
    175 
    176 #if DUMP_STATISTICS
    177     if (++numLists > numListsHighWaterMark)
    178         numListsHighWaterMark = numLists;
    179     imp->sizeHighWaterMark = 0;
    180 #endif
    181 }
    182 
    183 void List::markValues()
    184 {
    185     static_cast<ListImp *>(_impBase)->markValues();
    186 }
    187 
    188 void List::release()
    189 {   
    190     ASSERT(JSLock::lockCount() > 0);
    191    
    192     ListImp *imp = static_cast<ListImp *>(_impBase);
    193    
    194 #if DUMP_STATISTICS
    195     --numLists;
    196     ++numListsDestroyed;
    197     for (int i = 0; i < 17; i++)
    198         if (imp->sizeHighWaterMark > i)
    199             ++numListsBiggerThan[i];
    200 #endif
    201 
    202     delete [] imp->overflow;
    203     imp->overflow = 0;
    204 
    205     if (imp->state == usedInPool) {
    206         imp->state = unusedInPool;
    207         imp->nextInFreeList = poolFreeList;
    208         poolFreeList = imp;
    209         poolUsed--;
    210     } else {
    211         ASSERT(imp->state == usedOnHeap);
    212         HeapListImp *list = static_cast<HeapListImp *>(imp);
    213 
    214         // unlink from heap list
    215         if (!list->prevInHeapList) {
    216             heapList = list->nextInHeapList;
    217             if (heapList) {
    218                 heapList->prevInHeapList = NULL;
    219             }
    220         } else {
    221             list->prevInHeapList->nextInHeapList = list->nextInHeapList;
    222             if (list->nextInHeapList) {
    223                 list->nextInHeapList->prevInHeapList = list->prevInHeapList;
    224             }
    225         }
    226 
    227         delete list;
    228     }
    229 }
    230 
    231 JSValue *List::at(int i) const
    232 {
    233     ListImp *imp = static_cast<ListImp *>(_impBase);
    234     if ((unsigned)i >= (unsigned)imp->size)
    235         return jsUndefined();
    236     if (i < inlineValuesSize)
    237         return imp->values[i];
    238     return imp->overflow[i - inlineValuesSize];
    239 }
    240 
    241 void List::clear()
    242 {
    243     _impBase->size = 0;
    244 }
    245 
    246 void List::append(JSValue *v)
    247 {
    248     ASSERT(JSLock::lockCount() > 0);
    249    
    250     ListImp *imp = static_cast<ListImp *>(_impBase);
    251 
    252     int i = imp->size++;
    253 
    254 #if DUMP_STATISTICS
    255     if (imp->size > listSizeHighWaterMark)
    256         listSizeHighWaterMark = imp->size;
    257 #endif
    258 
    259     if (i < inlineValuesSize) {
    260         imp->values[i] = v;
    261         return;
    262     }
    263    
    264     if (i >= imp->capacity) {
    265         int newCapacity = i * 2;
    266         JSValue** newOverflow = new JSValue* [newCapacity - inlineValuesSize];
    267         JSValue** oldOverflow = imp->overflow;
    268         int oldOverflowSize = i - inlineValuesSize;
    269         for (int j = 0; j != oldOverflowSize; j++)
    270             newOverflow[j] = oldOverflow[j];
    271         delete [] oldOverflow;
    272         imp->overflow = newOverflow;
    273         imp->capacity = newCapacity;
    274     }
    275    
    276     imp->overflow[i - inlineValuesSize] = v;
    277 }
    278 
    279 void List::slice(int startIndex, List& result) const
    280 {
    281     ListImp *imp = static_cast<ListImp *>(_impBase);
    282 
    283     int size = imp->size;
    284 
    285     int inlineSize = min(size, inlineValuesSize);
    286     for (int i = startIndex; i < inlineSize; ++i)
    287         result.append(imp->values[i]);
    288 
    289     JSValue** overflow = imp->overflow;
    290     int overflowSize = size - inlineSize;
    291     for (int i = 0; i < overflowSize; ++i)
    292         result.append(overflow[i]);
    293 }
    294 
    295 const List& List::empty()
    296 {
    297     static List* staticEmptyList = new List;
    298     return *staticEmptyList;
     77    m_vector.uncheckedAppend(v);
    29978}
    30079
  • trunk/JavaScriptCore/kjs/list.h

    r27373 r27448  
    11/*
    2  *  This file is part of the KDE libraries
    32 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    4  *  Copyright (C) 2003 Apple Computer, Inc.
     3 *  Copyright (C) 2003, 2007 Apple Computer, Inc.
    54 *
    65 *  This library is free software; you can redistribute it and/or
     
    2423#define KJS_LIST_H
    2524
    26 #include "value.h"
     25#include <kjs/value.h>
     26#include <wtf/HashSet.h>
     27#include <wtf/Noncopyable.h>
     28#include <wtf/Vector.h>
    2729
    2830namespace KJS {
    2931
    30     struct ListImpBase {
    31         int size;
    32         int refCount;
    33         int valueRefCount; // FIXME: Get rid of this.
     32    class JSValue;
     33    class List;
     34   
     35    class List : Noncopyable {
     36    private:
     37        typedef Vector<JSValue*, 8> VectorType;
     38        typedef HashSet<List*> ListSet;
     39
     40    public:
     41        typedef VectorType::iterator iterator;
     42        typedef VectorType::const_iterator const_iterator;
     43
     44        List()
     45            : m_isInMarkSet(false)
     46        {
     47        }
     48
     49        ~List()
     50        {
     51            if (m_isInMarkSet)
     52                markSet().remove(this);
     53        }
     54
     55        int size() const { return m_vector.size(); }
     56        bool isEmpty() const { return m_vector.isEmpty(); }
     57
     58        JSValue* at(size_t i) const
     59        {
     60            if (i < m_vector.size())
     61                return m_vector.at(i);
     62            return jsUndefined();
     63        }
     64
     65        JSValue* operator[](int i) const { return at(i); }
     66
     67        void clear() { m_vector.clear(); }
     68
     69        void append(JSValue* v)
     70        {
     71            if (m_vector.size() < m_vector.capacity())
     72                m_vector.uncheckedAppend(v);
     73            else
     74                // Putting the slow "expand and append" case all in one
     75                // function measurably improves the performance of the fast
     76                // "just append" case.
     77                expandAndAppend(v);
     78        }
     79
     80        void getSlice(int startIndex, List& result) const;
     81
     82        iterator begin() { return m_vector.begin(); }
     83        iterator end() { return m_vector.end(); }
     84
     85        const_iterator begin() const { return m_vector.begin(); }
     86        const_iterator end() const { return m_vector.end(); }
     87
     88        static void markProtectedLists()
     89        {
     90            if (!markSet().size())
     91                return;
     92            markProtectedListsSlowCase();
     93        }
     94
     95        static const List& empty(); // Fast path for an empty list.
     96
     97    private:
     98        static ListSet& markSet();
     99        static void markProtectedListsSlowCase();
     100
     101        void expandAndAppend(JSValue*);
     102
     103        VectorType m_vector;
     104        bool m_isInMarkSet;
     105
     106    private:
     107        // Prohibits new / delete, which would break GC.
     108        void* operator new(size_t);
     109        void operator delete(void*);
     110
     111        void* operator new[](size_t);
     112        void operator delete[](void*);
     113
     114        void* operator new(size_t, void*);
     115        void operator delete(void*, size_t);
    34116    };
    35117   
    36     class ListIterator;
    37 
    38     /**
    39      * @short Native list type.
    40      *
    41      * List is a native ECMAScript type. List values are only used for
    42      * intermediate results of expression evaluation and cannot be stored
    43      * as properties of objects.
    44      */
    45     class List : Noncopyable {
    46     public:
    47         List();
    48         ~List() { deref(); }
    49 
    50         /**
    51          * Append an object to the end of the list.
    52          *
    53          * @param val Pointer to object.
    54          */
    55         void append(JSValue *val);
    56         /**
    57          * Remove all elements from the list.
    58          */
    59         void clear();
    60 
    61         void reset() { deref(); ++(_impBase = empty()._impBase)->refCount; }
    62 
    63         /**
    64          * Make a copy of the list, starting from startIndex.
    65          */
    66         void slice(int startIndex, List& result) const;
    67         /**
    68          * @return true if the list is empty. false otherwise.
    69          */
    70         bool isEmpty() const { return _impBase->size == 0; }
    71         /**
    72          * @return the current size of the list.
    73          */
    74         int size() const { return _impBase->size; }
    75         /**
    76          * @return A KJS::ListIterator pointing to the first element.
    77          */
    78         ListIterator begin() const;
    79         /**
    80          * @return A KJS::ListIterator pointing to the last element.
    81          */
    82         ListIterator end() const;
    83        
    84         /**
    85          * Retrieve an element at an indexed position. If you want to iterate
    86          * trough the whole list using KJS::ListIterator will be faster.
    87          *
    88          * @param i List index.
    89          * @return Return the element at position i. KJS::Undefined if the
    90          * index is out of range.
    91          */
    92         JSValue *at(int i) const;
    93         /**
    94          * Equivalent to at.
    95          */
    96         JSValue *operator[](int i) const { return at(i); }
    97    
    98         /**
    99          * Returns a pointer to a static instance of an empty list. Useful if a
    100          * function has a KJS::List parameter.
    101          */
    102         static const List &empty();
    103        
    104         static void markProtectedLists();
    105     private:
    106         ListImpBase *_impBase;
    107        
    108         void deref() { --_impBase->valueRefCount; if (--_impBase->refCount == 0) release(); }
    109 
    110         void release();
    111         void markValues();
    112     };
    113  
    114     /**
    115      * @short Iterator for KJS::List objects.
    116      */
    117     class ListIterator {
    118     public:
    119         /**
    120          * Construct an iterator that points to the first element of the list.
    121          * @param l The list the iterator will operate on.
    122          */
    123         ListIterator(const List &l) : _list(&l), _i(0) { }
    124         ListIterator(const List &l, int index) : _list(&l), _i(index) { }
    125         /**
    126          * Dereference the iterator.
    127          * @return A pointer to the element the iterator operates on.
    128          */
    129         JSValue *operator->() const { return _list->at(_i); }
    130         JSValue *operator*() const { return _list->at(_i); }
    131         /**
    132          * Prefix increment operator.
    133          * @return The element after the increment.
    134          */
    135         JSValue *operator++() { return _list->at(++_i); }
    136         /**
    137          * Postfix increment operator.
    138          */
    139         JSValue *operator++(int) { return _list->at(_i++); }
    140         /**
    141          * Prefix decrement operator.
    142          */
    143         JSValue *operator--() { return _list->at(--_i); }
    144         /**
    145          * Postfix decrement operator.
    146          */
    147         JSValue *operator--(int) { return _list->at(_i--); }
    148         /**
    149          * Compare the iterator with another one.
    150          * @return True if the two iterators operate on the same list element.
    151          * False otherwise.
    152          */
    153         bool operator==(const ListIterator &it) const { return _i == it._i; }
    154         /**
    155          * Check for inequality with another iterator.
    156          * @return True if the two iterators operate on different list elements.
    157          */
    158         bool operator!=(const ListIterator &it) const { return _i != it._i; }
    159 
    160     private:
    161         const List *_list;
    162         int _i;
    163     };
    164 
    165     inline ListIterator List::begin() const { return ListIterator(*this); }
    166     inline ListIterator List::end() const { return ListIterator(*this, size()); }
    167  
    168118} // namespace KJS
    169119
  • trunk/JavaScriptCore/kjs/regexp_object.cpp

    r27413 r27448  
    417417JSObject *RegExpObjectImp::construct(ExecState *exec, const List &args)
    418418{
    419   JSObject *o = args[0]->getObject();
     419  JSValue* arg0 = args[0];
     420  JSValue* arg1 = args[1];
     421 
     422  JSObject* o = arg0->getObject();
    420423  if (o && o->inherits(&RegExpImp::info)) {
    421     if (!args[1]->isUndefined())
     424    if (!arg1->isUndefined())
    422425      return throwError(exec, TypeError);
    423426    return o;
    424427  }
    425428 
    426   UString p = args[0]->isUndefined() ? UString("") : args[0]->toString(exec);
    427   UString flags = args[1]->isUndefined() ? UString("") : args[1]->toString(exec);
     429  UString p = arg0->isUndefined() ? UString("") : arg0->toString(exec);
     430  UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
    428431
    429432  RegExpPrototype* proto = static_cast<RegExpPrototype*>(exec->lexicalInterpreter()->builtinRegExpPrototype());
  • trunk/JavaScriptCore/kjs/string_object.cpp

    r27413 r27448  
    481481    break;
    482482  case Concat: {
    483     ListIterator it = args.begin();
    484     for ( ; it != args.end() ; ++it) {
    485         s += it->toString(exec);
     483    List::const_iterator end = args.end();
     484    for (List::const_iterator it = args.begin(); it != end; ++it) {
     485        s += (*it)->toString(exec);
    486486    }
    487487    result = jsString(s);
     
    809809  if (args.size() == 0)
    810810    return new StringInstance(proto);
    811   return new StringInstance(proto, args.begin()->toString(exec));
     811  return new StringInstance(proto, args[0]->toString(exec));
    812812}
    813813
     
    838838    UChar *buf = static_cast<UChar *>(fastMalloc(args.size() * sizeof(UChar)));
    839839    UChar *p = buf;
    840     ListIterator it = args.begin();
    841     while (it != args.end()) {
    842       unsigned short u = static_cast<unsigned short>(it->toUInt32(exec));
     840    List::const_iterator end = args.end();
     841    for (List::const_iterator it = args.begin(); it != end; ++it) {
     842      unsigned short u = static_cast<unsigned short>((*it)->toUInt32(exec));
    843843      *p++ = UChar(u);
    844       it++;
    845844    }
    846845    s = UString(buf, args.size(), false);
  • trunk/JavaScriptCore/wtf/Vector.h

    r26618 r27448  
    457457        template<typename U> void append(const U*, size_t);
    458458        template<typename U> void append(const U&);
     459        template<typename U> void uncheckedAppend(const U& val);
    459460        template<typename U, size_t c> void append(const Vector<U, c>&);
    460461
     
    666667        if (size() == capacity())
    667668            ptr = expandCapacity(size() + 1, ptr);
     669        new (end()) T(*ptr);
     670        ++m_size;
     671    }
     672
     673    // This version of append saves a branch in the case where you know that the
     674    // vector's capacity is large enough for the append to succeed.
     675
     676    template<typename T, size_t inlineCapacity> template<typename U>
     677    inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val)
     678    {
     679        ASSERT(size() < capacity());
     680        const U* ptr = &val;
    668681        new (end()) T(*ptr);
    669682        ++m_size;
  • trunk/WebCore/ChangeLog

    r27444 r27448  
     12007-11-04  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Darin Adler.
     4       
     5        http://bugs.webkit.org/show_bug.cgi?id=15835
     6
     7        Small adaptations to new KJS::List class.
     8
     9        * bindings/js/kjs_window.cpp:
     10        (KJS::WindowFunc::callAsFunction):
     11        (KJS::ScheduledAction::ScheduledAction):
     12
    1132007-11-05  Adam Roben  <[email protected]>
    214
  • trunk/WebCore/bindings/js/kjs_window.cpp

    r27433 r27448  
    13911391     
    13921392      List argsTail;
    1393       args.slice(2, argsTail);
     1393      args.getSlice(2, argsTail);
    13941394
    13951395      int r = (const_cast<Window*>(window))->installTimeout(func, argsTail, i, true /*single shot*/);
     
    14111411
    14121412      List argsTail;
    1413       args.slice(2, argsTail);
     1413      args.getSlice(2, argsTail);
    14141414
    14151415      int r = (const_cast<Window*>(window))->installTimeout(func, argsTail, i, false);
     
    15601560    : m_func(func)
    15611561{
    1562     ListIterator it = args.begin();
    1563     ListIterator end = args.end();
    1564     while (it != end)
     1562    List::const_iterator end = args.end();
     1563    for (List::const_iterator it = args.begin(); it != end; ++it)
    15651564        m_args.append(*it);
    15661565}
  • trunk/WebKit/ChangeLog

    r27402 r27448  
     12007-11-05  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Darin Adler.
     4       
     5        http://bugs.webkit.org/show_bug.cgi?id=15835
     6
     7        Small adaptations to new KJS::List class.
     8
     9        * ForwardingHeaders/kjs/value.h: Added.
     10
    1112007-11-03  David D. Kilzer  <[email protected]>
    212
Note: See TracChangeset for help on using the changeset viewer.