Changeset 2846 in webkit


Ignore:
Timestamp:
Nov 23, 2002, 11:49:26 PM (23 years ago)
Author:
mjs
Message:
  • completed Darin's mostly-fix for 3037795 - Resource use increases when accessing very high index value in array

The two missing pieces were handling sparse properties when
shrinking the array, and when sorting. Thse are now both taken
care of.

  • kjs/array_instance.h:
  • kjs/array_object.cpp: (ArrayInstanceImp::put): (ArrayInstanceImp::deleteProperty): (ArrayInstanceImp::resizeStorage): (ArrayInstanceImp::setLength): (ArrayInstanceImp::sort): (ArrayInstanceImp::pushUndefinedObjectsToEnd):
  • kjs/identifier.h:
  • kjs/object.h:
  • kjs/property_map.cpp:
  • kjs/property_map.h:
  • kjs/reference_list.cpp: (ReferenceList::append): (ReferenceList::length):
  • kjs/reference_list.h:
  • kjs/ustring.cpp: (UString::toUInt32):
  • kjs/ustring.h:
Location:
trunk/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r2845 r2846  
     12002-11-23  Maciej Stachowiak  <[email protected]>
     2
     3        - completed Darin's mostly-fix for 3037795 - Resource use
     4        increases when accessing very high index value in array
     5
     6        The two missing pieces were handling sparse properties when
     7        shrinking the array, and when sorting. Thse are now both taken
     8        care of.
     9       
     10        * kjs/array_instance.h:
     11        * kjs/array_object.cpp:
     12        (ArrayInstanceImp::put):
     13        (ArrayInstanceImp::deleteProperty):
     14        (ArrayInstanceImp::resizeStorage):
     15        (ArrayInstanceImp::setLength):
     16        (ArrayInstanceImp::sort):
     17        (ArrayInstanceImp::pushUndefinedObjectsToEnd):
     18        * kjs/identifier.h:
     19        * kjs/object.h:
     20        * kjs/property_map.cpp:
     21        * kjs/property_map.h:
     22        * kjs/reference_list.cpp:
     23        (ReferenceList::append):
     24        (ReferenceList::length):
     25        * kjs/reference_list.h:
     26        * kjs/ustring.cpp:
     27        (UString::toUInt32):
     28        * kjs/ustring.h:
     29
    1302002-11-23  Maciej Stachowiak  <[email protected]>
    231
  • trunk/JavaScriptCore/ChangeLog-2002-12-03

    r2845 r2846  
     12002-11-23  Maciej Stachowiak  <[email protected]>
     2
     3        - completed Darin's mostly-fix for 3037795 - Resource use
     4        increases when accessing very high index value in array
     5
     6        The two missing pieces were handling sparse properties when
     7        shrinking the array, and when sorting. Thse are now both taken
     8        care of.
     9       
     10        * kjs/array_instance.h:
     11        * kjs/array_object.cpp:
     12        (ArrayInstanceImp::put):
     13        (ArrayInstanceImp::deleteProperty):
     14        (ArrayInstanceImp::resizeStorage):
     15        (ArrayInstanceImp::setLength):
     16        (ArrayInstanceImp::sort):
     17        (ArrayInstanceImp::pushUndefinedObjectsToEnd):
     18        * kjs/identifier.h:
     19        * kjs/object.h:
     20        * kjs/property_map.cpp:
     21        * kjs/property_map.h:
     22        * kjs/reference_list.cpp:
     23        (ReferenceList::append):
     24        (ReferenceList::length):
     25        * kjs/reference_list.h:
     26        * kjs/ustring.cpp:
     27        (UString::toUInt32):
     28        * kjs/ustring.h:
     29
    1302002-11-23  Maciej Stachowiak  <[email protected]>
    231
  • trunk/JavaScriptCore/ChangeLog-2003-10-25

    r2845 r2846  
     12002-11-23  Maciej Stachowiak  <[email protected]>
     2
     3        - completed Darin's mostly-fix for 3037795 - Resource use
     4        increases when accessing very high index value in array
     5
     6        The two missing pieces were handling sparse properties when
     7        shrinking the array, and when sorting. Thse are now both taken
     8        care of.
     9       
     10        * kjs/array_instance.h:
     11        * kjs/array_object.cpp:
     12        (ArrayInstanceImp::put):
     13        (ArrayInstanceImp::deleteProperty):
     14        (ArrayInstanceImp::resizeStorage):
     15        (ArrayInstanceImp::setLength):
     16        (ArrayInstanceImp::sort):
     17        (ArrayInstanceImp::pushUndefinedObjectsToEnd):
     18        * kjs/identifier.h:
     19        * kjs/object.h:
     20        * kjs/property_map.cpp:
     21        * kjs/property_map.h:
     22        * kjs/reference_list.cpp:
     23        (ReferenceList::append):
     24        (ReferenceList::length):
     25        * kjs/reference_list.h:
     26        * kjs/ustring.cpp:
     27        (UString::toUInt32):
     28        * kjs/ustring.h:
     29
    1302002-11-23  Maciej Stachowiak  <[email protected]>
    231
  • trunk/JavaScriptCore/kjs/array_instance.h

    r2786 r2846  
    5353   
    5454  private:
    55     void setLength(unsigned newLength);
     55    void setLength(unsigned newLength, ExecState *exec);
    5656   
    57     unsigned pushUndefinedObjectsToEnd();
     57    unsigned pushUndefinedObjectsToEnd(ExecState *exec);
    5858   
     59    void resizeStorage(unsigned);
     60
    5961    unsigned length;
    6062    unsigned storageLength;
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r2843 r2846  
    105105{
    106106  if (propertyName == lengthPropertyName) {
    107     setLength(value.toUInt32(exec));
     107    setLength(value.toUInt32(exec), exec);
    108108    return;
    109109  }
     
    113113  if (ok) {
    114114    if (length <= index)
    115       setLength(index + 1);
     115      setLength(index + 1, exec);
    116116    if (index < storageLength) {
    117117      storage[index] = value.imp();
     
    126126{
    127127  if (length <= index)
    128     setLength(index + 1);
     128    setLength(index + 1, exec);
    129129  if (index < storageLength) {
    130130    storage[index] = value.imp();
     
    172172 
    173173  bool ok;
    174   unsigned index = propertyName.toULong(&ok);
     174  uint32_t index = propertyName.toUInt32(&ok);
    175175  if (ok) {
    176176    if (index >= length)
     
    197197}
    198198
    199 void ArrayInstanceImp::setLength(unsigned newLength)
    200 {
    201   if (newLength <= sparseArrayCutoff || newLength == length + 1) {
     199void ArrayInstanceImp::resizeStorage(unsigned newLength)
     200{
    202201    if (newLength < storageLength) {
    203202      memset(storage + newLength, 0, sizeof(ValueImp *) * (storageLength - newLength));
     
    210209    }
    211210    storageLength = newLength;
    212   }
    213  
    214   // FIXME: Need to remove items from the property map when making a sparse
    215   // list shorter.
     211}
     212
     213void ArrayInstanceImp::setLength(unsigned newLength, ExecState *exec)
     214{
     215  if (newLength <= MAX(sparseArrayCutoff,storageLength) || newLength == length + 1) {
     216    resizeStorage(newLength);
     217  }
     218
     219  if (newLength < length) {
     220    ReferenceList sparseProperties;
     221   
     222    _prop.addSparseArrayPropertiesToReferenceList(sparseProperties, Object(this));
     223   
     224    ReferenceListIterator it = sparseProperties.begin();
     225    while (it != sparseProperties.end()) {
     226      Reference ref = it++;
     227      bool ok;
     228      if (ref.getPropertyName(exec).toULong(&ok) > newLength) {
     229        ref.deleteValue(exec);
     230      }
     231    }
     232  }
    216233 
    217234  length = newLength;
     
    239256void ArrayInstanceImp::sort(ExecState *exec)
    240257{
    241     int lengthNotIncludingUndefined = pushUndefinedObjectsToEnd();
     258    int lengthNotIncludingUndefined = pushUndefinedObjectsToEnd(exec);
    242259   
    243260    execForCompareByStringForQSort = exec;
     
    277294void ArrayInstanceImp::sort(ExecState *exec, Object &compareFunction)
    278295{
    279     int lengthNotIncludingUndefined = pushUndefinedObjectsToEnd();
     296    int lengthNotIncludingUndefined = pushUndefinedObjectsToEnd(exec);
    280297   
    281298    CompareWithCompareFunctionArguments args(exec, compareFunction.imp());
     
    285302}
    286303
    287 unsigned ArrayInstanceImp::pushUndefinedObjectsToEnd()
     304unsigned ArrayInstanceImp::pushUndefinedObjectsToEnd(ExecState *exec)
    288305{
    289306    ValueImp *undefined = UndefinedImp::staticUndefined;
     
    300317    }
    301318   
    302     // FIXME: Get sparse items down here.
    303    
    304     if (o != storageLength)
     319    ReferenceList sparseProperties;
     320    _prop.addSparseArrayPropertiesToReferenceList(sparseProperties, Object(this));
     321    unsigned newLength = o + sparseProperties.length();
     322
     323    if (newLength > storageLength) {
     324      resizeStorage(newLength);
     325    }
     326
     327    ReferenceListIterator it = sparseProperties.begin();
     328    while (it != sparseProperties.end()) {
     329      Reference ref = it++;
     330      storage[o] = ref.getValue(exec).imp();
     331      ObjectImp::deleteProperty(exec, ref.getPropertyName(exec));
     332      o++;
     333    }
     334   
     335    if (newLength != storageLength)
    305336        memset(storage + o, 0, sizeof(ValueImp *) * (storageLength - o));
    306337   
  • trunk/JavaScriptCore/kjs/identifier.h

    r2776 r2846  
    5050       
    5151        unsigned long toULong(bool *ok) const { return _ustring.toULong(ok); }
     52        uint32_t toUInt32(bool *ok) const { return _ustring.toUInt32(ok); }
    5253        double toDouble() const { return _ustring.toDouble(); }
    5354       
  • trunk/JavaScriptCore/kjs/object.h

    r2824 r2846  
    598598    void restoreProperties(const SavedProperties &p) { _prop.restore(p); }
    599599
     600  protected:
     601    PropertyMap _prop;
    600602  private:
    601603    const HashEntry* findPropertyHashEntry( const Identifier& propertyName ) const;
    602     PropertyMap _prop;
    603604    ValueImp *_proto;
    604605    ValueImp *_internalValue;
  • trunk/JavaScriptCore/kjs/property_map.cpp

    r2834 r2846  
    370370}
    371371
     372void PropertyMap::addSparseArrayPropertiesToReferenceList(ReferenceList &list, const Object &base) const
     373{
     374#if USE_SINGLE_ENTRY
     375    UString::Rep *key = _singleEntry.key;
     376    if (key) {
     377      UString k(key);
     378      bool fitsInUInt32;
     379      k.toUInt32(&fitsInUInt32);
     380      if (fitsInUInt32) {
     381        list.append(Reference(base, Identifier(key)));
     382      }
     383    }
     384#endif
     385    if (!_table) {
     386      return;
     387    }
     388
     389    for (int i = 0; i != _table->size; ++i) {
     390      UString::Rep *key = _table->entries[i].key;
     391      if (key) {
     392        UString k(key);
     393        bool fitsInUInt32;
     394        k.toUInt32(&fitsInUInt32);
     395        if (fitsInUInt32) {
     396          list.append(Reference(base, Identifier(key)));
     397        }
     398      }
     399    }
     400}
     401
    372402void PropertyMap::save(SavedProperties &p) const
    373403{
  • trunk/JavaScriptCore/kjs/property_map.h

    r2821 r2846  
    7272        void mark() const;
    7373        void addEnumerablesToReferenceList(ReferenceList &, const Object &) const;
     74        void addSparseArrayPropertiesToReferenceList(ReferenceList &, const Object &) const;
    7475
    7576        void save(SavedProperties &) const;
  • trunk/JavaScriptCore/kjs/reference_list.cpp

    r1841 r2846  
    4242    ReferenceListHeadNode(const Reference &ref) : ReferenceListNode(ref), refcount(1) {}
    4343    int refcount;
     44    int length;
    4445  };
    4546
     
    9394    tail = tail->next;
    9495  }
     96  head->length++;
     97}
     98
     99int ReferenceList::length()
     100{
     101  return head ? head->length : 0;
    95102}
    96103
  • trunk/JavaScriptCore/kjs/reference_list.h

    r1844 r2846  
    5454
    5555    void append(const Reference& val);
    56    
     56    int length();
     57
    5758    ReferenceListIterator begin() const;
    5859    ReferenceListIterator end() const;
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r2800 r2846  
    552552}
    553553
     554uint32_t UString::toUInt32(bool *ok) const
     555{
     556  double d = toDouble();
     557  bool b = true;
     558
     559  if (isNaN(d) || d != static_cast<uint32_t>(d)) {
     560    b = false;
     561    d = 0;
     562  }
     563
     564  if (ok)
     565    *ok = b;
     566
     567  return static_cast<uint32_t>(d);
     568}
     569
    554570int UString::find(const UString &f, int pos) const
    555571{
  • trunk/JavaScriptCore/kjs/ustring.h

    r2800 r2846  
    3333#endif
    3434
     35#include <stdint.h>
     36
    3537/**
    3638 * @internal
     
    384386     */
    385387    unsigned long toULong(bool *ok = 0L) const;
     388
     389    uint32_t toUInt32(bool *ok = 0L) const;
     390
    386391    /**
    387392     * @return Position of first occurence of f starting at position pos.
Note: See TracChangeset for help on using the changeset viewer.