Ignore:
Timestamp:
Nov 20, 2002, 1:49:31 PM (23 years ago)
Author:
darin
Message:
  • oops, checked in big regression instead of 5% speedup
  • kjs/function.cpp: (ActivationImp::ActivationImp): Make a marking list, not a refing list.
  • a cut at the sparse array implementation
  • kjs/array_instance.h: Keep storageLength separate from length.
  • kjs/array_object.cpp: (ArrayInstanceImp::ArrayInstanceImp): Start with storageLength == length. (ArrayInstanceImp::get): Check against storage length. (ArrayInstanceImp::put): Ditto. (ArrayInstanceImp::hasProperty): Ditto. (ArrayInstanceImp::deleteProperty): Ditto. (ArrayInstanceImp::setLength): Only enlarge storage length up to a cutoff. (ArrayInstanceImp::mark): Use storageLength. (ArrayInstanceImp::pushUndefinedObjectsToEnd): Added FIXME.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/array_object.cpp

    r2783 r2786  
    3838// ------------------------------ ArrayInstanceImp -----------------------------
    3939
     40const unsigned sparseArrayCutoff = 10000;
     41
    4042const ClassInfo ArrayInstanceImp::info = {"Array", 0, 0, 0};
    4143
     
    4345  : ObjectImp(proto)
    4446  , length(initialLength)
    45   , capacity(length)
    46   , storage(length ? (ValueImp **)calloc(length, sizeof(ValueImp *)) : 0)
     47  , storageLength(initialLength)
     48  , capacity(storageLength)
     49  , storage(capacity ? (ValueImp **)calloc(capacity, sizeof(ValueImp *)) : 0)
    4750{
    4851}
     
    5154  : ObjectImp(proto)
    5255  , length(list.size())
    53   , capacity(length)
    54   , storage(length ? (ValueImp **)malloc(sizeof(ValueImp *) * length) : 0)
     56  , storageLength(length)
     57  , capacity(storageLength)
     58  , storage(capacity ? (ValueImp **)malloc(sizeof(ValueImp *) * capacity) : 0)
    5559{
    5660  ListIterator it = list.begin();
     
    7680    if (index >= length)
    7781      return Undefined();
     82    if (index < storageLength) {
     83      ValueImp *v = storage[index];
     84      return v ? Value(v) : Undefined();
     85    }
     86  }
     87
     88  return ObjectImp::get(exec, propertyName);
     89}
     90
     91Value ArrayInstanceImp::get(ExecState *exec, unsigned index) const
     92{
     93  if (index >= length)
     94    return Undefined();
     95  if (index < storageLength) {
    7896    ValueImp *v = storage[index];
    7997    return v ? Value(v) : Undefined();
    8098  }
    81 
    82   return ObjectImp::get(exec, propertyName);
    83 }
    84 
    85 Value ArrayInstanceImp::get(ExecState *exec, unsigned index) const
    86 {
    87   if (index >= length)
    88     return Undefined();
    89   ValueImp *v = storage[index];
    90   return v ? Value(v) : Undefined();
     99 
     100  return ObjectImp::get(exec, Identifier::from(index));
    91101}
    92102
     
    104114    if (length <= index)
    105115      setLength(index + 1);
     116    if (index < storageLength) {
     117      storage[index] = value.imp();
     118      return;
     119    }
     120  }
     121 
     122  ObjectImp::put(exec, propertyName, value, attr);
     123}
     124
     125void ArrayInstanceImp::put(ExecState *exec, unsigned index, const Value &value, int attr)
     126{
     127  if (length <= index)
     128    setLength(index + 1);
     129  if (index < storageLength) {
    106130    storage[index] = value.imp();
    107131    return;
    108132  }
    109133 
    110   ObjectImp::put(exec, propertyName, value, attr);
    111 }
    112 
    113 void ArrayInstanceImp::put(ExecState *exec, unsigned index, const Value &value, int attr)
    114 {
    115   if (length <= index)
    116     setLength(index + 1);
    117   storage[index] = value.imp();
     134  ObjectImp::put(exec, Identifier::from(index), value, attr);
    118135}
    119136
     
    128145    if (index >= length)
    129146      return false;
     147    if (index < storageLength) {
     148      ValueImp *v = storage[index];
     149      return v && v != UndefinedImp::staticUndefined;
     150    }
     151  }
     152 
     153  return ObjectImp::hasProperty(exec, propertyName);
     154}
     155
     156bool ArrayInstanceImp::hasProperty(ExecState *exec, unsigned index) const
     157{
     158  if (index >= length)
     159    return false;
     160  if (index < storageLength) {
    130161    ValueImp *v = storage[index];
    131162    return v && v != UndefinedImp::staticUndefined;
    132163  }
    133164 
    134   return ObjectImp::hasProperty(exec, propertyName);
    135 }
    136 
    137 bool ArrayInstanceImp::hasProperty(ExecState *exec, unsigned index) const
    138 {
    139   if (index >= length)
    140     return false;
    141   ValueImp *v = storage[index];
    142   return v && v != UndefinedImp::staticUndefined;
     165  return ObjectImp::hasProperty(exec, Identifier::from(index));
    143166}
    144167
     
    153176    if (index >= length)
    154177      return true;
     178    if (index < storageLength) {
     179      storage[index] = 0;
     180      return true;
     181    }
     182  }
     183 
     184  return ObjectImp::deleteProperty(exec, propertyName);
     185}
     186
     187bool ArrayInstanceImp::deleteProperty(ExecState *exec, unsigned index)
     188{
     189  if (index >= length)
     190    return true;
     191  if (index < storageLength) {
    155192    storage[index] = 0;
    156193    return true;
    157194  }
    158195 
    159   return ObjectImp::deleteProperty(exec, propertyName);
    160 }
    161 
    162 bool ArrayInstanceImp::deleteProperty(ExecState *exec, unsigned index)
    163 {
    164   if (index >= length)
    165     return true;
    166   storage[index] = 0;
    167   return true;
     196  return ObjectImp::deleteProperty(exec, Identifier::from(index));
    168197}
    169198
    170199void ArrayInstanceImp::setLength(unsigned newLength)
    171200{
    172   if (newLength < length) {
    173     memset(storage + newLength, 0, sizeof(ValueImp *) * (length - newLength));
    174   }
    175   if (newLength > capacity) {
    176     unsigned newCapacity = (newLength * 3 + 1) / 2;
    177     storage = (ValueImp **)realloc(storage, newCapacity * sizeof (ValueImp *));
    178     memset(storage + capacity, 0, sizeof(ValueImp *) * (newCapacity - capacity));
    179     capacity = newCapacity;
    180   }
     201  if (newLength <= sparseArrayCutoff || newLength == length + 1) {
     202    if (newLength < storageLength) {
     203      memset(storage + newLength, 0, sizeof(ValueImp *) * (storageLength - newLength));
     204    }
     205    if (newLength > capacity) {
     206      unsigned newCapacity = (newLength * 3 + 1) / 2;
     207      storage = (ValueImp **)realloc(storage, newCapacity * sizeof (ValueImp *));
     208      memset(storage + capacity, 0, sizeof(ValueImp *) * (newCapacity - capacity));
     209      capacity = newCapacity;
     210    }
     211    storageLength = newLength;
     212  }
     213 
     214  // FIXME: Need to remove items from the property map when making a sparse
     215  // list shorter.
     216 
    181217  length = newLength;
    182218}
     
    185221{
    186222  ObjectImp::mark();
    187   unsigned l = length;
     223  unsigned l = storageLength;
    188224  for (unsigned i = 0; i < l; ++i) {
    189225    ValueImp *imp = storage[i];
     
    253289
    254290    unsigned o = 0;
    255     for (unsigned i = 0; i != length; ++i) {
     291   
     292    for (unsigned i = 0; i != storageLength; ++i) {
    256293        ValueImp *v = storage[i];
    257294        if (v && v != undefined) {
     
    261298        }
    262299    }
    263     if (o != length)
    264         memset(storage + o, 0, sizeof(ValueImp *) * (length - o));
     300   
     301    // FIXME: Get sparse items down here.
     302   
     303    if (o != storageLength)
     304        memset(storage + o, 0, sizeof(ValueImp *) * (storageLength - o));
     305   
    265306    return o;
    266307}
Note: See TracChangeset for help on using the changeset viewer.