Ignore:
Timestamp:
Nov 20, 2002, 4:55:08 PM (23 years ago)
Author:
darin
Message:
  • created argument list objects only on demand for a 7.5% speedup
  • kjs/function.h: Change ActivationImp around.
  • kjs/function.cpp: (FunctionImp::call): Pass a pointer to the arguments list to avoid ref/unref. (FunctionImp::get): Get the function pointer from the context directly, not the activation object. (ArgumentsImp::ArgumentsImp): Add an overload that takes no arguments. (ActivationImp::ActivationImp): Store a context pointer and an arguments object pointer. (ActivationImp::get): Special case for arguments, create it and return it. (ActivationImp::put): Special case for arguments, can't be set. (ActivationImp::hasProperty): Special case for arguments, return true. (ActivationImp::deleteProperty): Special case for arguments, refuse to delete. (ActivationImp::mark): Mark the arguments object. (ActivationImp::createArgumentsObject): Do the work of actually creating it. (GlobalFuncImp::call): Use stack-based objects for the ContextImp and ExecState.
  • kjs/internal.h: Keep function and arguments pointer in the context.
  • kjs/internal.cpp: (ContextImp::ContextImp): Don't pass in the func and args when making an ActivationImp. (InterpreterImp::evaluate): Use stack-based objects here.
  • kjs/types.h: Add ArgumentList as a synonym for List, soon to be separate.
File:
1 edited

Legend:

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

    r2786 r2792  
    6666}
    6767
    68 void FunctionImp::mark()
    69 {
    70   InternalFunctionImp::mark();
    71 }
    72 
    7368bool FunctionImp::implementsCall() const
    7469{
     
    9994  // enter a new execution context
    10095  ContextImp ctx(globalObj, exec, thisObj, codeType(),
    101                  exec->context().imp(), this, args);
     96                 exec->context().imp(), this, &args);
    10297  ExecState newExec(exec->interpreter(), &ctx);
    10398  newExec.setException(exec->exception()); // could be null
     
    211206        ContextImp *context = exec->_context;
    212207        while (context) {
    213             ActivationImp *activation = static_cast<ActivationImp *>(context->activationObject());
    214             if (activation->function() == this)
    215                 return activation->get(exec, propertyName);
     208            if (context->function() == this)
     209                return static_cast<ActivationImp *>
     210                    (context->activationObject())->get(exec, propertyName);
    216211            context = context->callingContext();
    217212        }
     
    318313
    319314// ECMA 10.1.8
     315ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func)
     316  : ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), 0)
     317{
     318  Value protect(this);
     319  putDirect(calleePropertyName, func, DontEnum);
     320}
     321
    320322ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args)
    321323  : ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), args)
     
    330332
    331333// ECMA 10.1.6
    332 ActivationImp::ActivationImp(ExecState *exec, FunctionImp *f, const List &args)
    333   : _function(f), _arguments(true)
    334 {
    335   Value protect(this);
    336   _arguments = args;
    337   _argumentsObject = new ArgumentsImp(exec, f, args);
    338   putDirect(argumentsPropertyName, _argumentsObject, Internal|DontDelete);
     334ActivationImp::ActivationImp(ExecState *exec)
     335    : _context(exec->context().imp()), _argumentsObject(0)
     336{
     337  // FIXME: Do we need to support enumerating the arguments property?
     338}
     339
     340Value ActivationImp::get(ExecState *exec, const Identifier &propertyName) const
     341{
     342    if (propertyName == argumentsPropertyName) {
     343        if (!_argumentsObject)
     344            createArgumentsObject(exec);
     345        return Value(_argumentsObject);
     346    }
     347    return ObjectImp::get(exec, propertyName);
     348}
     349
     350void ActivationImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
     351{
     352    if (propertyName == argumentsPropertyName) {
     353        // FIXME: Do we need to allow overwriting this?
     354        return;
     355    }
     356    ObjectImp::put(exec, propertyName, value, attr);
     357}
     358
     359bool ActivationImp::hasProperty(ExecState *exec, const Identifier &propertyName) const
     360{
     361    if (propertyName == argumentsPropertyName)
     362        return true;
     363    return ObjectImp::hasProperty(exec, propertyName);
     364}
     365
     366bool ActivationImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
     367{
     368    if (propertyName == argumentsPropertyName)
     369        return false;
     370    return ObjectImp::deleteProperty(exec, propertyName);
     371}
     372
     373void ActivationImp::mark()
     374{
     375    if (_argumentsObject && !_argumentsObject->marked())
     376        _argumentsObject->mark();
     377    ObjectImp::mark();
     378}
     379
     380void ActivationImp::createArgumentsObject(ExecState *exec) const
     381{
     382    FunctionImp *function = _context->function();
     383    const ArgumentList *arguments = _context->arguments();
     384    if (arguments)
     385        _argumentsObject = new ArgumentsImp(exec, function, *arguments);
     386    else
     387        _argumentsObject = new ArgumentsImp(exec, function);
    339388}
    340389
     
    392441      // enter a new execution context
    393442      Object thisVal(Object::dynamicCast(exec->context().thisValue()));
    394       ContextImp *ctx = new ContextImp(exec->interpreter()->globalObject(),
    395                                        exec,
    396                                        thisVal,
    397                                        EvalCode,
    398                                        exec->context().imp());
    399 
    400       ExecState *newExec = new ExecState(exec->interpreter(),ctx);
    401       newExec->setException(exec->exception()); // could be null
     443      ContextImp ctx(exec->interpreter()->globalObject(),
     444                     exec,
     445                     thisVal,
     446                     EvalCode,
     447                     exec->context().imp());
     448
     449      ExecState newExec(exec->interpreter(), &ctx);
     450      newExec.setException(exec->exception()); // could be null
    402451
    403452      // execute the code
    404       Completion c = progNode->execute(newExec);
     453      Completion c = progNode->execute(&newExec);
    405454
    406455      // if an exception occured, propogate it back to the previous execution object
    407       if (newExec->hadException())
    408         exec->setException(newExec->exception());
    409       delete newExec;
    410       delete ctx;
     456      if (newExec.hadException())
     457        exec->setException(newExec.exception());
    411458
    412459      if ( progNode->deref() )
Note: See TracChangeset for help on using the changeset viewer.