Changeset 27068 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Oct 25, 2007, 2:37:45 PM (18 years ago)
Author:
ggaren
Message:

Reviewed by Oliver Hunt.


Fixed http://bugs.webkit.org/show_bug.cgi?id=15694
Shrink the size of an activation object by 1 word


This is in preparation for adding a symbol table to the activation
object.


The basic strategy here is to rely on the mutual exclusion between
the arguments object pointer and the function pointer (you only need
the latter in order to create the former), and store them in the same
place. The LazyArgumentsObject class encapsulates this strategy.


Also inlined the ArgumentsImp constructor, for good measure.


SunSpider reports no regression. Regression tests pass.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • kjs/Context.cpp: (KJS::Context::~Context):
  • kjs/function.cpp: (KJS::ActivationImp::LazyArgumentsObject::createArgumentsObject): (KJS::ActivationImp::LazyArgumentsObject::mark): (KJS::): (KJS::ActivationImp::argumentsGetter): (KJS::ActivationImp::mark):
  • kjs/function.h: (KJS::ActivationImp::LazyArgumentsObject::LazyArgumentsObject): (KJS::ActivationImp::LazyArgumentsObject::getOrCreate): (KJS::ActivationImp::LazyArgumentsObject::resetArguments): (KJS::ActivationImp::LazyArgumentsObject::setArgumentsObject): (KJS::ActivationImp::LazyArgumentsObject::argumentsObject): (KJS::ActivationImp::LazyArgumentsObject::setFunction): (KJS::ActivationImp::LazyArgumentsObject::function): (KJS::ActivationImp::LazyArgumentsObject::createdArgumentsObject): (KJS::ActivationImp::LazyArgumentsObject::): (KJS::ActivationImp::ActivationImp::ActivationImp): (KJS::ActivationImp::resetArguments):
Location:
trunk/JavaScriptCore/kjs
Files:
3 edited

Legend:

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

    r27027 r27068  
    8888    ActivationImp* activation = static_cast<ActivationImp*>(m_activation);
    8989    if (activation)
    90         activation->releaseArguments();
     90        activation->resetArguments();
    9191}
    9292
  • trunk/JavaScriptCore/kjs/function.cpp

    r27025 r27068  
    391391// ------------------------------ ActivationImp --------------------------------
    392392
     393void ActivationImp::LazyArgumentsObject::createArgumentsObject(ExecState* exec, ActivationImp* activationImp)
     394{
     395    setArgumentsObject(new Arguments(exec, function(), arguments, activationImp));
     396
     397    // The arguments list is only needed to create the arguments object, so
     398    // discard it now. This prevents lists of Lists from building up, waiting
     399    // to be garbage collected.
     400    arguments.reset();
     401}
     402
     403void ActivationImp::LazyArgumentsObject::mark()
     404{
     405    JSObject* o;
     406    if (createdArgumentsObject())
     407        o = argumentsObject();
     408    else
     409        o = function();
     410
     411    if (!o->marked())
     412        o->mark();
     413}
     414
    393415const ClassInfo ActivationImp::info = {"Activation", 0, 0, 0};
    394416
    395 // ECMA 10.1.6
    396 ActivationImp::ActivationImp(FunctionImp* function, const List& arguments)
    397     : _function(function), _arguments(arguments), _argumentsObject(0)
    398 {
    399   // FIXME: Do we need to support enumerating the arguments property?
    400 }
    401 
    402417JSValue* ActivationImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
    403418{
    404419  ActivationImp* thisObj = static_cast<ActivationImp*>(slot.slotBase());
    405 
    406   // default: return builtin arguments array
    407   if (!thisObj->_argumentsObject)
    408     thisObj->createArgumentsObject(exec);
    409  
    410   return thisObj->_argumentsObject;
     420  return thisObj->m_lazyArgumentsObject.getOrCreate(exec, thisObj);
    411421}
    412422
     
    453463void ActivationImp::mark()
    454464{
    455     if (_function && !_function->marked())
    456         _function->mark();
    457     if (_argumentsObject && !_argumentsObject->marked())
    458         _argumentsObject->mark();
     465    m_lazyArgumentsObject.mark();
    459466    JSObject::mark();
    460 }
    461 
    462 void ActivationImp::createArgumentsObject(ExecState* exec)
    463 {
    464   _argumentsObject = new Arguments(exec, _function, _arguments, const_cast<ActivationImp*>(this));
    465   // The arguments list is only needed to create the arguments object, so discard it now
    466   _arguments.reset();
    467467}
    468468
  • trunk/JavaScriptCore/kjs/function.h

    r27025 r27068  
    144144  class ActivationImp : public JSObject {
    145145  public:
    146     ActivationImp(FunctionImp* function, const List& arguments);
     146    class LazyArgumentsObject {
     147    public:
     148        LazyArgumentsObject(FunctionImp* f, const List& a)
     149            : arguments(a)
     150        {
     151            ASSERT(f);
     152            setFunction(f);
     153        }
     154
     155        Arguments* getOrCreate(ExecState* exec, ActivationImp* activationImp)
     156        {
     157            if (!createdArgumentsObject())
     158                createArgumentsObject(exec, activationImp);
     159            return argumentsObject();
     160        }
     161
     162        void resetArguments() { arguments.reset(); }
     163        void mark();
     164
     165    private:
     166        static const uintptr_t TagMask = 1; // Pointer alignment leaves this bit open for tagging.
     167       
     168        void setArgumentsObject(Arguments* a)
     169        {
     170            u.argumentsObject = a;
     171            u.bits |= TagMask;
     172        }
     173
     174        Arguments* argumentsObject()
     175        {
     176            ASSERT(createdArgumentsObject());
     177            return reinterpret_cast<Arguments*>(u.bits & ~TagMask);
     178        }
     179
     180        void setFunction(FunctionImp* f) { u.function = f; }
     181        FunctionImp* function()
     182        {
     183            ASSERT(!createdArgumentsObject());
     184            return u.function;
     185        }
     186
     187        bool createdArgumentsObject() { return (u.bits & TagMask) != 0; }
     188        void createArgumentsObject(ExecState*, ActivationImp*);
     189
     190        List arguments;
     191        union {
     192            // The low bit in this union is a flag: 0 means the union holds a
     193            // FunctionImp*; 1 means the union holds an Arguments*.
     194            uintptr_t bits;
     195            FunctionImp* function;
     196            Arguments* argumentsObject;
     197        } u;
     198    };
     199   
     200    ActivationImp::ActivationImp(FunctionImp* function, const List& arguments)
     201        : m_lazyArgumentsObject(function, arguments)
     202    {
     203    }
    147204
    148205    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     
    157214    bool isActivation() { return true; }
    158215
    159     void releaseArguments() { _arguments.reset(); }
     216    void resetArguments() { m_lazyArgumentsObject.resetArguments(); }
    160217
    161218  private:
    162219    static PropertySlot::GetValueFunc getArgumentsGetter();
    163220    static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
    164     void createArgumentsObject(ExecState*);
    165 
    166     FunctionImp* _function;
    167     List _arguments;
    168     mutable Arguments* _argumentsObject;
     221   
     222    LazyArgumentsObject m_lazyArgumentsObject;
    169223  };
    170224
Note: See TracChangeset for help on using the changeset viewer.