Commit 5b1e7b71 authored by darin's avatar darin

- 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.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@2792 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent c562dc6b
2002-11-20 Darin Adler <darin@apple.com>
- 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.
2002-11-20 Maciej Stachowiak <mjs@apple.com>
Reduced the size of ValueImp by 8 bytes for a .5% speedup.
......
2002-11-20 Darin Adler <darin@apple.com>
- 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.
2002-11-20 Maciej Stachowiak <mjs@apple.com>
Reduced the size of ValueImp by 8 bytes for a .5% speedup.
......
2002-11-20 Darin Adler <darin@apple.com>
- 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.
2002-11-20 Maciej Stachowiak <mjs@apple.com>
Reduced the size of ValueImp by 8 bytes for a .5% speedup.
......
......@@ -65,11 +65,6 @@ FunctionImp::~FunctionImp()
delete param;
}
void FunctionImp::mark()
{
InternalFunctionImp::mark();
}
bool FunctionImp::implementsCall() const
{
return true;
......@@ -98,7 +93,7 @@ Value FunctionImp::call(ExecState *exec, Object &thisObj, const List &args)
// enter a new execution context
ContextImp ctx(globalObj, exec, thisObj, codeType(),
exec->context().imp(), this, args);
exec->context().imp(), this, &args);
ExecState newExec(exec->interpreter(), &ctx);
newExec.setException(exec->exception()); // could be null
......@@ -210,9 +205,9 @@ Value FunctionImp::get(ExecState *exec, const Identifier &propertyName) const
if (propertyName == argumentsPropertyName) {
ContextImp *context = exec->_context;
while (context) {
ActivationImp *activation = static_cast<ActivationImp *>(context->activationObject());
if (activation->function() == this)
return activation->get(exec, propertyName);
if (context->function() == this)
return static_cast<ActivationImp *>
(context->activationObject())->get(exec, propertyName);
context = context->callingContext();
}
return Undefined();
......@@ -317,6 +312,13 @@ void DeclaredFunctionImp::processVarDecls(ExecState *exec)
const ClassInfo ArgumentsImp::info = {"Arguments", 0, 0, 0};
// ECMA 10.1.8
ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func)
: ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), 0)
{
Value protect(this);
putDirect(calleePropertyName, func, DontEnum);
}
ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args)
: ArrayInstanceImp(exec->interpreter()->builtinObjectPrototype().imp(), args)
{
......@@ -329,13 +331,60 @@ ArgumentsImp::ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args)
const ClassInfo ActivationImp::info = {"Activation", 0, 0, 0};
// ECMA 10.1.6
ActivationImp::ActivationImp(ExecState *exec, FunctionImp *f, const List &args)
: _function(f), _arguments(true)
ActivationImp::ActivationImp(ExecState *exec)
: _context(exec->context().imp()), _argumentsObject(0)
{
Value protect(this);
_arguments = args;
_argumentsObject = new ArgumentsImp(exec, f, args);
putDirect(argumentsPropertyName, _argumentsObject, Internal|DontDelete);
// FIXME: Do we need to support enumerating the arguments property?
}
Value ActivationImp::get(ExecState *exec, const Identifier &propertyName) const
{
if (propertyName == argumentsPropertyName) {
if (!_argumentsObject)
createArgumentsObject(exec);
return Value(_argumentsObject);
}
return ObjectImp::get(exec, propertyName);
}
void ActivationImp::put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr)
{
if (propertyName == argumentsPropertyName) {
// FIXME: Do we need to allow overwriting this?
return;
}
ObjectImp::put(exec, propertyName, value, attr);
}
bool ActivationImp::hasProperty(ExecState *exec, const Identifier &propertyName) const
{
if (propertyName == argumentsPropertyName)
return true;
return ObjectImp::hasProperty(exec, propertyName);
}
bool ActivationImp::deleteProperty(ExecState *exec, const Identifier &propertyName)
{
if (propertyName == argumentsPropertyName)
return false;
return ObjectImp::deleteProperty(exec, propertyName);
}
void ActivationImp::mark()
{
if (_argumentsObject && !_argumentsObject->marked())
_argumentsObject->mark();
ObjectImp::mark();
}
void ActivationImp::createArgumentsObject(ExecState *exec) const
{
FunctionImp *function = _context->function();
const ArgumentList *arguments = _context->arguments();
if (arguments)
_argumentsObject = new ArgumentsImp(exec, function, *arguments);
else
_argumentsObject = new ArgumentsImp(exec, function);
}
// ------------------------------ GlobalFunc -----------------------------------
......@@ -391,23 +440,21 @@ Value GlobalFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args
// enter a new execution context
Object thisVal(Object::dynamicCast(exec->context().thisValue()));
ContextImp *ctx = new ContextImp(exec->interpreter()->globalObject(),
exec,
thisVal,
EvalCode,
exec->context().imp());
ContextImp ctx(exec->interpreter()->globalObject(),
exec,
thisVal,
EvalCode,
exec->context().imp());
ExecState *newExec = new ExecState(exec->interpreter(),ctx);
newExec->setException(exec->exception()); // could be null
ExecState newExec(exec->interpreter(), &ctx);
newExec.setException(exec->exception()); // could be null
// execute the code
Completion c = progNode->execute(newExec);
Completion c = progNode->execute(&newExec);
// if an exception occured, propogate it back to the previous execution object
if (newExec->hadException())
exec->setException(newExec->exception());
delete newExec;
delete ctx;
if (newExec.hadException())
exec->setException(newExec.exception());
if ( progNode->deref() )
delete progNode;
......
......@@ -45,8 +45,6 @@ namespace KJS {
virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual void mark();
virtual bool implementsCall() const;
virtual Value call(ExecState *exec, Object &thisObj, const List &args);
......@@ -93,6 +91,7 @@ namespace KJS {
class ArgumentsImp : public ArrayInstanceImp {
public:
ArgumentsImp(ExecState *exec, FunctionImp *func);
ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args);
virtual const ClassInfo *classInfo() const { return &info; }
......@@ -101,17 +100,23 @@ namespace KJS {
class ActivationImp : public ObjectImp {
public:
ActivationImp(ExecState *exec, FunctionImp *f, const List &args);
ActivationImp(ExecState *exec);
virtual Value get(ExecState *exec, const Identifier &propertyName) const;
virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
virtual const ClassInfo *classInfo() const { return &info; }
static const ClassInfo info;
FunctionImp *function() const { return _function; }
virtual void mark();
private:
FunctionImp *_function;
List _arguments;
ObjectImp *_argumentsObject;
void createArgumentsObject(ExecState *exec) const;
const ContextImp *_context;
mutable ArgumentsImp *_argumentsObject;
};
class GlobalFuncImp : public InternalFunctionImp {
......
......@@ -355,17 +355,17 @@ void LabelStack::clear()
// ------------------------------ ContextImp -----------------------------------
// ECMA 10.2
ContextImp::ContextImp(Object &glob, ExecState *exec, Object &thisV, CodeType type,
ContextImp *_callingContext, FunctionImp *func, const List &args)
ContextImp *_callingContext, FunctionImp *func, const ArgumentList *args)
: _function(func), _arguments(args)
{
codeType = type;
callingCon = _callingContext;
// create and initialize activation object (ECMA 10.1.6)
if (type == FunctionCode || type == AnonymousCode ) {
activation = Object(new ActivationImp(exec,func,args));
activation = Object(new ActivationImp(exec));
variable = activation;
} else {
activation = Object();
......@@ -781,14 +781,9 @@ Completion InterpreterImp::evaluate(const UString &code, const Value &thisV)
}
else {
// execute the code
ExecState *exec1 = 0;
ContextImp *ctx = new ContextImp(globalObj, exec1, thisObj);
ExecState *newExec = new ExecState(m_interpreter,ctx);
res = progNode->execute(newExec);
delete newExec;
delete ctx;
ContextImp ctx(globalObj, 0, thisObj);
ExecState newExec(m_interpreter,&ctx);
res = progNode->execute(&newExec);
}
if (progNode->deref())
......
......@@ -199,8 +199,8 @@ namespace KJS {
class ContextImp {
public:
ContextImp(Object &glob, ExecState *exec, Object &thisV, CodeType type = GlobalCode,
ContextImp *_callingContext = 0L, FunctionImp *func = 0L, const List &args = List());
virtual ~ContextImp();
ContextImp *_callingContext = 0L, FunctionImp *func = 0L, const ArgumentList *args = 0);
~ContextImp();
const List scopeChain() const { return scope; }
Object variableObject() const { return variable; }
......@@ -208,6 +208,8 @@ namespace KJS {
Object thisValue() const { return thisVal; }
ContextImp *callingContext() { return callingCon; }
ObjectImp *activationObject() { return activation.imp(); }
FunctionImp *function() const { return _function; }
const ArgumentList *arguments() const { return _arguments; }
void pushScope(const Object &s);
void popScope();
......@@ -220,7 +222,8 @@ namespace KJS {
Object thisVal;
ContextImp *callingCon;
Object activation;
FunctionImp *_function;
const ArgumentList *_arguments;
LabelStack ls;
CodeType codeType;
......
......@@ -200,6 +200,8 @@ namespace KJS {
ListHookNode *hook;
bool m_needsMarking;
};
typedef List ArgumentList;
}; // namespace
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment