Changeset 1825 in webkit for trunk/JavaScriptCore/kjs/value.cpp


Ignore:
Timestamp:
Aug 15, 2002, 5:02:07 AM (23 years ago)
Author:
mjs
Message:

Phase 2 of fixnum optimization. Store any integral number that
will fit in two bits less than a long inside the ValueImp *
itself, thus avoiding the need to deal with the garbage collector
at all for these types. Such numbers comprised .5 million of the
1.7 million ValueImps created during the cvs-js-performance test,
so traffic through the garbage collector should be

20% improvement on cvs-js-performance. This may also show up on
cvs-base, but I did not compare and I am too lazy to make clean in
WebCore yet again.

This also significantly reduces memory footprint on
JavaScript-heavy pages. Size after going through
cvs-js-performance suite is now down from 22 MB to 17.5 MB.

  • JavaScriptCore.pbproj/project.pbxproj:
  • kjs/simple_number.h: Added. Some inline static methods for handling simple numbers that are stored in the pointer.
  • kjs/ustring.h:
  • kjs/ustring.cpp: (UString::from): Added new overload for long.
  • kjs/value.cpp: (ValueImp::marked): Add special case for simple numbers. (ValueImp::setGcAllowed): Likewise. (ValueImp::toInteger): Call dispatch version of toUInt32(unsigned&), not the real method. (ValueImp::toInt32): Likewise. (ValueImp::toUInt32): Likewise. (ValueImp::toUInt16): Likewise. (ValueImp::dispatchType): Add special case for simple numbers. (ValueImp::dispatchToPrimitive): Likewise. (ValueImp::dispatchToBoolean): Likewise. (ValueImp::dispatchToNumber): Likewise. (ValueImp::dispatchToString): Likewise. (ValueImp::dispatchToObject): Likewise. (ValueImp::dispatchToUInt32): Likewise. (ValueImp::dispatchGetBase): Likewise. (ValueImp::dispatchGetPropertyName): Likewise. (ValueImp::dispatchPutValue): Likewise. (ValueImp::dispatchDeleteValue): Likewise. (Number::Number): Create a simple number instead of a full-blown ValueImp when possible. (Number::value): Likewise.
  • kjs/value.h:
File:
1 edited

Legend:

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

    r1824 r1825  
    3737#include "error_object.h"
    3838#include "nodes.h"
     39#include "simple_number.h"
    3940
    4041using namespace KJS;
     
    6465bool ValueImp::marked() const
    6566{
    66   // FIXNUM: need special case for fixnum, they should act as if
    67   // always marked.
    68   return (_flags & VI_MARKED);
     67  // simple numbers are always considered marked
     68  return SimpleNumber::isSimpleNumber(this) || (_flags & VI_MARKED);
    6969}
    7070
    7171void ValueImp::setGcAllowed()
    7272{
    73   // FIXNUM: need special case for fixnum, should be a no-op
    74   //fprintf(stderr,"ValueImp::setGcAllowed %p\n",(void*)this);
    75   _flags |= VI_GCALLOWED;
     73  // simple numbers are never seen by the collector so setting this
     74  // flag is irrelevant
     75  if (!SimpleNumber::isSimpleNumber(this)) {
     76    //fprintf(stderr,"ValueImp::setGcAllowed %p\n",(void*)this);
     77    _flags |= VI_GCALLOWED;
     78  }
    7679}
    7780
     
    9598{
    9699  unsigned i;
    97   if (toUInt32(i))
     100  if (dispatchToUInt32(i))
    98101    return (int)i;
    99102  return int(roundValue(exec, Value(const_cast<ValueImp*>(this))));
     
    103106{
    104107  unsigned i;
    105   if (toUInt32(i))
     108  if (dispatchToUInt32(i))
    106109    return (int)i;
    107110
     
    118121{
    119122  unsigned i;
    120   if (toUInt32(i))
     123  if (dispatchToUInt32(i))
    121124    return i;
    122125
     
    130133{
    131134  unsigned i;
    132   if (toUInt32(i))
     135  if (dispatchToUInt32(i))
    133136    return (unsigned short)i;
    134137
     
    181184Type ValueImp::dispatchType() const
    182185{
    183   // FIXNUM: need special case for fixnums here
    184   return this->type();
     186  if (SimpleNumber::isSimpleNumber(this)) {
     187    return NumberType;
     188  } else {
     189    return this->type();
     190  }
    185191}
    186192
    187193Value ValueImp::dispatchToPrimitive(ExecState *exec, Type preferredType) const
    188194{
    189   // FIXNUM: need special case for fixnums here
    190   return this->toPrimitive(exec, preferredType);
     195  if (SimpleNumber::isSimpleNumber(this)) {
     196    return Number((NumberImp*)this);
     197  } else {
     198    return this->toPrimitive(exec, preferredType);
     199  }
    191200}
    192201
    193202bool ValueImp::dispatchToBoolean(ExecState *exec) const
    194203{
    195   // FIXNUM: need special case for fixnums here
    196   return this->toBoolean(exec);
     204  if (SimpleNumber::isSimpleNumber(this)) {
     205    return SimpleNumber::longValue(this);
     206  } else {
     207    return this->toBoolean(exec);
     208  }
    197209}
    198210
    199211double ValueImp::dispatchToNumber(ExecState *exec) const
    200212{
    201   // FIXNUM: need special case for fixnums here
    202   return this->toNumber(exec);
     213  if (SimpleNumber::isSimpleNumber(this)) {
     214    return SimpleNumber::longValue(this);
     215  } else {
     216    return this->toNumber(exec);
     217  }
    203218}
    204219
    205220UString ValueImp::dispatchToString(ExecState *exec) const
    206221{
    207   // FIXNUM: need special case for fixnums here
    208   return this->toString(exec);
     222  if (SimpleNumber::isSimpleNumber(this)) {
     223    return UString::from(SimpleNumber::longValue(this));
     224  } else {
     225    return this->toString(exec);
     226  }
    209227}
    210228
    211229Object ValueImp::dispatchToObject(ExecState *exec) const
    212230{
    213   // FIXNUM: need special case for fixnums here
    214   return this->toObject(exec);
     231  if (SimpleNumber::isSimpleNumber(this)) {
     232      List args;
     233      args.append(Number(static_cast<NumberImp*>(const_cast<ValueImp *>(this))));
     234      return Object::dynamicCast(exec->interpreter()->builtinNumber().construct(exec,args));
     235  } else {
     236    return this->toObject(exec);
     237  }
    215238}
    216239
    217240bool ValueImp::dispatchToUInt32(unsigned& result) const
    218241{
    219   // FIXNUM: need special case for fixnums here
    220   return this->toUInt32(result);
     242  if (SimpleNumber::isSimpleNumber(this)) {
     243    result = SimpleNumber::longValue(this);
     244    return true;
     245  } else {
     246    return this->toUInt32(result);
     247  }
    221248}
    222249
    223250Value ValueImp::dispatchGetBase(ExecState *exec) const
    224251{
    225   // FIXNUM: need special case for fixnums here
    226   return this->getBase(exec);
     252  if (SimpleNumber::isSimpleNumber(this)) {
     253    Object err = Error::create(exec, ReferenceError, I18N_NOOP("Invalid reference base"));
     254    exec->setException(err);
     255    return err;
     256  } else {
     257    return this->getBase(exec);
     258  }
    227259}
    228260
    229261UString ValueImp::dispatchGetPropertyName(ExecState *exec) const
    230262{
    231   // FIXNUM: need special case for fixnums here
    232   return this->getPropertyName(exec);
    233 }
    234 
    235 #if 0
    236 Value ValueImp::dispatchGetValue(ExecState *exec) const
    237 {
    238   // FIXNUM: need special case for fixnums here
    239   return this->getValue(exec);
    240 }
    241 #endif
     263  if (SimpleNumber::isSimpleNumber(this)) {
     264    return UString();
     265  } else {
     266    return this->getPropertyName(exec);
     267  }
     268}
    242269
    243270void ValueImp::dispatchPutValue(ExecState *exec, const Value& w)
    244271{
    245   // FIXNUM: need special case for fixnums here
    246   return this->putValue(exec, w);
     272  if (SimpleNumber::isSimpleNumber(this)) {
     273    Object err = Error::create(exec,ReferenceError);
     274    exec->setException(err);
     275  } else {
     276    return this->putValue(exec, w);
     277  }
    247278}
    248279
    249280bool ValueImp::dispatchDeleteValue(ExecState *exec)
    250281{
    251   // FIXNUM: need special case for fixnums here
    252   return this->deleteValue(exec);
     282  if (SimpleNumber::isSimpleNumber(this)) {
     283    Object err = Error::create(exec,ReferenceError);
     284    exec->setException(err);
     285    return false;
     286  } else {
     287    return this->deleteValue(exec);
     288  }
    253289}
    254290
     
    372408// ------------------------------ Number ---------------------------------------
    373409
    374 // FIXNUM: need fixnum special case in below constructor
    375410Number::Number(int i)
    376   : Value(new NumberImp(static_cast<double>(i))) { }
    377 
    378 // FIXNUM: need fixnum special case in below constructor
     411  : Value(SimpleNumber::fitsInSimpleNumber(i) ? SimpleNumber::makeSimpleNumber(i) : new NumberImp(static_cast<double>(i))) { }
     412
    379413Number::Number(unsigned int u)
    380   : Value(new NumberImp(static_cast<double>(u))) { }
    381 
    382 // FIXNUM: need fixnum special case in below constructor
     414  : Value(SimpleNumber::fitsInSimpleNumber(u) ? SimpleNumber::makeSimpleNumber(u) : new NumberImp(static_cast<double>(u))) { }
     415
    383416Number::Number(double d)
    384   : Value(new NumberImp(d)) { }
    385 
    386 // FIXNUM: need fixnum special case in below constructor
     417  : Value(SimpleNumber::fitsInSimpleNumber((long)d) ? SimpleNumber::makeSimpleNumber((long)d) : new NumberImp(d)) { }
     418
    387419Number::Number(long int l)
    388   : Value(new NumberImp(static_cast<double>(l))) { }
    389 
    390 // FIXNUM: need fixnum special case in below constructor
     420  : Value(SimpleNumber::fitsInSimpleNumber(l) ? SimpleNumber::makeSimpleNumber(l) : new NumberImp(static_cast<double>(l))) { }
     421
    391422Number::Number(long unsigned int l)
    392   : Value(new NumberImp(static_cast<double>(l))) { }
     423  : Value(SimpleNumber::fitsInSimpleNumber(l) ? SimpleNumber::makeSimpleNumber(l) : new NumberImp(static_cast<double>(l))) { }
    393424
    394425Number Number::dynamicCast(const Value &v)
     
    402433double Number::value() const
    403434{
    404   assert(rep);
    405   return ((NumberImp*)rep)->value();
     435  if (SimpleNumber::isSimpleNumber(rep)) {
     436    return (double)SimpleNumber::longValue(rep);
     437  } else {
     438    assert(rep);
     439    return ((NumberImp*)rep)->value();
     440  }
    406441}
    407442
Note: See TracChangeset for help on using the changeset viewer.