Commit f3eb7aae authored by darin@apple.com's avatar darin@apple.com

Reviewed by Eric.

        - http://bugs.webkit.org/show_bug.cgi?id=16471
          Completions need to be smaller (or not exist at all)

        SuSpider shows 2.4% speedup.

        Stop using completions in the execution engine.
        Instead, the completion type and label target are both
        stored in the ExecState.

        * API/JSContextRef.cpp: Removed unneeded include of "completion.h".
        * bindings/runtime_method.cpp: Removed unused execute function.
        * bindings/runtime_method.h: Ditto.

        * kjs/ExecState.h: Added completionType, breakOrContinueTarget,
        setCompletionType, setNormalCompletion, setBreakCompletion,
        setContinueCompletion, setReturnValueCompletion, setThrowCompletion,
        setInterruptedCompletion, m_completionType, and m_breakOrContinueTarget.

        * kjs/completion.h: Removed constructor and getter for target
        for break and continue from Completion. This class is now only
        used for the public API to Interpreter and such.

        * kjs/date_object.h: Removed unused execute function.

        * kjs/function.cpp:
        (KJS::FunctionImp::callAsFunction): Removed some unneeded
        exception processing. Updated to call the new execute function
        and to get the completion type from the ExecState. Merged in
        the execute function, which repeated some of the same logic and
        was called only from here.
        (KJS::GlobalFuncImp::callAsFunction): More of the same for eval.
        * kjs/function.h: Removed execute.

        * kjs/interpreter.cpp:
        (KJS::Interpreter::evaluate): Added code to convert the result of
        execut into a Completion.

        * kjs/nodes.cpp:
        (KJS::Node::setErrorCompletion): Renamed from createErrorCompletion.
        Now sets the completion type in the ExecState.
        (KJS::Node::rethrowException): Now sets the completion type in the
        ExecState.
        (KJS::StatementNode::hitStatement): Now sets the completion type in
        the ExecState.
        (KJS::VarStatementNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::statementListExecute): Ditto. Also changed the for loop to use
        indices instead of iterators.
        (KJS::BlockNode::execute): Updated return type.
        (KJS::EmptyStatementNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::ExprStatementNode::execute): Ditto.
        (KJS::IfNode::execute): Ditto.
        (KJS::DoWhileNode::execute): Ditto. Also streamlined the logic a little
        to make the normal case a little faster and moved the end outside the
        loop so that "break" can do a break.
        (KJS::WhileNode::execute): Ditto.
        (KJS::ForNode::execute): Ditto.
        (KJS::ForInNode::execute): Ditto.
        (KJS::ContinueNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::BreakNode::execute): Ditto.
        (KJS::ReturnNode::execute): Ditto.
        (KJS::WithNode::execute): Ditto.
        (KJS::CaseClauseNode::executeStatements): Ditto. Also renamed to have
        execute in its name to reflect the fact that it's a member of the same
        family of functions.
        (KJS::CaseBlockNode::executeBlock): Ditto.
        (KJS::SwitchNode::execute): Ditto.
        (KJS::LabelNode::execute): Ditto.
        (KJS::ThrowNode::execute): Ditto.
        (KJS::TryNode::execute): Ditto.
        (KJS::ProgramNode::execute): Ditto.
        (KJS::EvalNode::execute): Ditto.
        (KJS::FunctionBodyNode::execute): Ditto.
        (KJS::FuncDeclNode::execute): Ditto.

        * kjs/nodes.h: Renamed setErrorCompletion to createErrorCompletion, made
        hitStatement protected, changed return value of execute to a JSValue,
        renamed evalStatements to executeStatements, and evalBlock to executeBlock.

        * kjs/number_object.h: Removed unused execute function.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@28887 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent bff92787
......@@ -31,7 +31,6 @@
#include "JSCallbackObject.h"
#include "JSClassRef.h"
#include "JSGlobalObject.h"
#include "completion.h"
#include "object.h"
#include <wtf/Platform.h>
......
2007-12-20 Darin Adler <darin@apple.com>
Reviewed by Eric.
- http://bugs.webkit.org/show_bug.cgi?id=16471
Completions need to be smaller (or not exist at all)
SuSpider shows 2.4% speedup.
Stop using completions in the execution engine.
Instead, the completion type and label target are both
stored in the ExecState.
* API/JSContextRef.cpp: Removed unneeded include of "completion.h".
* bindings/runtime_method.cpp: Removed unused execute function.
* bindings/runtime_method.h: Ditto.
* kjs/ExecState.h: Added completionType, breakOrContinueTarget,
setCompletionType, setNormalCompletion, setBreakCompletion,
setContinueCompletion, setReturnValueCompletion, setThrowCompletion,
setInterruptedCompletion, m_completionType, and m_breakOrContinueTarget.
* kjs/completion.h: Removed constructor and getter for target
for break and continue from Completion. This class is now only
used for the public API to Interpreter and such.
* kjs/date_object.h: Removed unused execute function.
* kjs/function.cpp:
(KJS::FunctionImp::callAsFunction): Removed some unneeded
exception processing. Updated to call the new execute function
and to get the completion type from the ExecState. Merged in
the execute function, which repeated some of the same logic and
was called only from here.
(KJS::GlobalFuncImp::callAsFunction): More of the same for eval.
* kjs/function.h: Removed execute.
* kjs/interpreter.cpp:
(KJS::Interpreter::evaluate): Added code to convert the result of
execut into a Completion.
* kjs/nodes.cpp:
(KJS::Node::setErrorCompletion): Renamed from createErrorCompletion.
Now sets the completion type in the ExecState.
(KJS::Node::rethrowException): Now sets the completion type in the
ExecState.
(KJS::StatementNode::hitStatement): Now sets the completion type in
the ExecState.
(KJS::VarStatementNode::execute): Updated to put completion type in
the ExecState instead of a Completion object.
(KJS::statementListExecute): Ditto. Also changed the for loop to use
indices instead of iterators.
(KJS::BlockNode::execute): Updated return type.
(KJS::EmptyStatementNode::execute): Updated to put completion type in
the ExecState instead of a Completion object.
(KJS::ExprStatementNode::execute): Ditto.
(KJS::IfNode::execute): Ditto.
(KJS::DoWhileNode::execute): Ditto. Also streamlined the logic a little
to make the normal case a little faster and moved the end outside the
loop so that "break" can do a break.
(KJS::WhileNode::execute): Ditto.
(KJS::ForNode::execute): Ditto.
(KJS::ForInNode::execute): Ditto.
(KJS::ContinueNode::execute): Updated to put completion type in
the ExecState instead of a Completion object.
(KJS::BreakNode::execute): Ditto.
(KJS::ReturnNode::execute): Ditto.
(KJS::WithNode::execute): Ditto.
(KJS::CaseClauseNode::executeStatements): Ditto. Also renamed to have
execute in its name to reflect the fact that it's a member of the same
family of functions.
(KJS::CaseBlockNode::executeBlock): Ditto.
(KJS::SwitchNode::execute): Ditto.
(KJS::LabelNode::execute): Ditto.
(KJS::ThrowNode::execute): Ditto.
(KJS::TryNode::execute): Ditto.
(KJS::ProgramNode::execute): Ditto.
(KJS::EvalNode::execute): Ditto.
(KJS::FunctionBodyNode::execute): Ditto.
(KJS::FuncDeclNode::execute): Ditto.
* kjs/nodes.h: Renamed setErrorCompletion to createErrorCompletion, made
hitStatement protected, changed return value of execute to a JSValue,
renamed evalStatements to executeStatements, and evalBlock to executeBlock.
* kjs/number_object.h: Removed unused execute function.
2007-12-20 Geoffrey Garen <ggaren@apple.com>
Added Radar number.
......
......@@ -92,8 +92,3 @@ JSValue *RuntimeMethod::callAsFunction(ExecState *exec, JSObject *thisObj, const
instance->end();
return aValue;
}
Completion RuntimeMethod::execute(ExecState*)
{
return Completion(Normal, jsUndefined());
}
......@@ -32,9 +32,7 @@
namespace KJS {
class RuntimeMethod : public InternalFunctionImp
{
class RuntimeMethod : public InternalFunctionImp {
public:
RuntimeMethod(ExecState *exec, const Identifier &n, Bindings::MethodList &methodList);
......@@ -42,8 +40,6 @@ public:
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
virtual Completion execute(ExecState *exec);
private:
static JSValue *lengthGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
......
......@@ -108,7 +108,69 @@ namespace KJS {
const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
LocalStorage& localStorage() { return *m_localStorage; }
// These are only valid right after calling execute().
ComplType completionType() const { return m_completionType; }
const Identifier& breakOrContinueTarget() const
{
ASSERT(m_completionType == Break || m_completionType == Continue);
return *m_breakOrContinueTarget;
}
// Only for use in the implementation of execute().
void setCompletionType(ComplType type)
{
ASSERT(type != Break);
ASSERT(type != Continue);
m_completionType = type;
}
JSValue* setNormalCompletion()
{
ASSERT(!hadException());
m_completionType = Normal;
return 0;
}
JSValue* setNormalCompletion(JSValue* value)
{
ASSERT(!hadException());
m_completionType = Normal;
return value;
}
JSValue* setBreakCompletion(const Identifier* target)
{
ASSERT(!hadException());
m_completionType = Break;
m_breakOrContinueTarget = target;
return 0;
}
JSValue* setContinueCompletion(const Identifier* target)
{
ASSERT(!hadException());
m_completionType = Continue;
m_breakOrContinueTarget = target;
return 0;
}
JSValue* setReturnValueCompletion(JSValue* returnValue)
{
ASSERT(!hadException());
ASSERT(returnValue);
m_completionType = ReturnValue;
return returnValue;
}
JSValue* setThrowCompletion(JSValue* exception)
{
ASSERT(!hadException());
ASSERT(exception);
m_completionType = Throw;
return exception;
}
JSValue* setInterruptedCompletion()
{
ASSERT(!hadException());
m_completionType = Interrupted;
return 0;
}
public:
ExecState(JSGlobalObject* glob, JSObject* thisV,
ScopeNode* scopeNode, CodeType type = GlobalCode,
......@@ -141,6 +203,9 @@ namespace KJS {
int m_iterationDepth;
int m_switchDepth;
CodeType m_codeType;
ComplType m_completionType;
const Identifier* m_breakOrContinueTarget;
};
} // namespace KJS
......
......@@ -26,7 +26,6 @@
namespace KJS {
class Identifier;
class JSValue;
enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
......@@ -44,20 +43,16 @@ namespace KJS {
class Completion {
public:
Completion(ComplType type = Normal, JSValue* value = 0)
: m_type(type), m_value(value), m_target(0) { }
Completion(ComplType type, const Identifier* target)
: m_type(type), m_value(0), m_target(target) { }
: m_type(type), m_value(value) { }
ComplType complType() const { return m_type; }
JSValue* value() const { return m_value; }
void setValue(JSValue* v) { m_value = v; }
const Identifier& target() const { return *m_target; }
bool isValueCompletion() const { return !!m_value; }
private:
ComplType m_type;
JSValue* m_value;
const Identifier* m_target;
};
}
......
......@@ -132,7 +132,6 @@ FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
virtual JSObject *construct(ExecState *, const List &args);
virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args);
Completion execute(const List &);
JSObject *construct(const List &);
};
......
......@@ -70,24 +70,14 @@ void FunctionImp::mark()
JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
// enter a new execution context
ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
if (exec->hadException())
newExec.setException(exec->exception());
Completion comp = execute(&newExec);
// if an exception occured, propogate it back to the previous execution object
if (newExec.hadException())
comp = Completion(Throw, newExec.exception());
if (comp.complType() == Throw) {
exec->setException(comp.value());
return comp.value();
}
else if (comp.complType() == ReturnValue)
return comp.value();
else
ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
JSValue* result = body->execute(&newExec);
if (newExec.completionType() == Throw) {
exec->setException(result);
return result;
}
if (newExec.completionType() == ReturnValue)
return result;
return jsUndefined();
}
......@@ -214,15 +204,6 @@ JSObject* FunctionImp::construct(ExecState* exec, const List& args)
return obj;
}
Completion FunctionImp::execute(ExecState* exec)
{
Completion result = body->execute(exec);
if (result.complType() == Throw || result.complType() == ReturnValue)
return result;
return Completion(Normal, jsUndefined()); // TODO: or ReturnValue ?
}
// ------------------------------ IndexToNameMap ---------------------------------
// We map indexes in the arguments array to their corresponding argument names.
......@@ -718,30 +699,21 @@ JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const
JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
JSObject* thisVal = static_cast<JSObject*>(exec->thisValue());
ExecState newExec(globalObject, thisVal, evalNode.get(), EvalCode, exec, globalObject->currentExec());
if (exec->hadException())
newExec.setException(exec->exception());
if (switchGlobal) {
newExec.pushScope(thisObj);
newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj));
}
Completion c = evalNode->execute(&newExec);
JSValue* value = evalNode->execute(&newExec);
if (switchGlobal)
newExec.popScope();
// if an exception occured, propogate it back to the previous execution object
if (newExec.hadException())
exec->setException(newExec.exception());
res = jsUndefined();
if (c.complType() == Throw)
exec->setException(c.value());
else if (c.isValueCompletion())
res = c.value();
if (exec->completionType() == Throw) {
exec->setException(value);
return value;
}
return value ? value : jsUndefined();
}
break;
}
case ParseInt:
res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
......
......@@ -82,7 +82,6 @@ namespace KJS {
virtual JSObject* construct(ExecState*, const List& args);
virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
Completion execute(ExecState*);
// Note: unlike body->paramName, this returns Identifier::null for parameters
// that will never get set, due to later param having the same name
......
......@@ -120,7 +120,8 @@ Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int
else {
// execute the code
ExecState newExec(globalObject, thisObj, progNode.get());
res = progNode->execute(&newExec);
JSValue* value = progNode->execute(&newExec);
res = Completion(newExec.completionType(), value);
}
globalObject->decRecursion();
......
This diff is collapsed.
This diff is collapsed.
......@@ -88,7 +88,6 @@ namespace KJS {
static const ClassInfo info;
enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
Completion execute(const List &);
JSObject *construct(const List &);
};
......
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