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:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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   
Note: See TracChangeset for help on using the changeset viewer.