Changeset 27589 in webkit for trunk/JavaScriptCore/kjs/nodes.h


Ignore:
Timestamp:
Nov 7, 2007, 11:58:15 PM (18 years ago)
Author:
[email protected]
Message:

2007-11-07 Eric Seidel <[email protected]>

Reviewed by Darin and Oliver.


Add evaluateToNumber parallel evaluation tree to speed up number operations.
Make ImmediateNumberNode a subclass of NumberNode.
Share evaluate logic between evaluate and evaluateToNumber using inline functions
There is still a lot of improvement to be made here.


SunSpider claims this is a 1.0% speedup overall (nbody 7.9%), base64 slowing 2.0%
Given the huge win that this prepares us for with simple type inferencing I see the small
regression in base64 being worth the substantial overall improvement.

  • kjs/grammar.y:
  • kjs/nodes.cpp: (KJS::Node::evaluateToNumber): (KJS::NumberNode::evaluate): (KJS::NumberNode::evaluateToNumber): (KJS::StringNode::evaluateToNumber): (KJS::LocalVarAccessNode::inlineEvaluate): (KJS::LocalVarAccessNode::evaluate): (KJS::LocalVarAccessNode::evaluateToNumber): (KJS::BracketAccessorNode::inlineEvaluate): (KJS::BracketAccessorNode::evaluate): (KJS::BracketAccessorNode::evaluateToNumber): (KJS::NegateNode::evaluate): (KJS::NegateNode::evaluateToNumber): (KJS::MultNode::inlineEvaluateToNumber): (KJS::MultNode::evaluate): (KJS::MultNode::evaluateToNumber): (KJS::DivNode::inlineEvaluateToNumber): (KJS::DivNode::evaluate): (KJS::DivNode::evaluateToNumber): (KJS::ModNode::inlineEvaluateToNumber): (KJS::ModNode::evaluate): (KJS::ModNode::evaluateToNumber): (KJS::throwOutOfMemoryErrorToNumber): (KJS::addSlowCaseToNumber): (KJS::add): (KJS::addToNumber): (KJS::AddNode::evaluateToNumber): (KJS::SubNode::inlineEvaluateToNumber): (KJS::SubNode::evaluate): (KJS::SubNode::evaluateToNumber): (KJS::valueForReadModifyAssignment): (KJS::ReadModifyLocalVarNode::evaluate): (KJS::ReadModifyResolveNode::evaluate): (KJS::ReadModifyDotNode::evaluate): (KJS::ReadModifyBracketNode::evaluate):
  • kjs/nodes.h: (KJS::Node::): (KJS::NumberNode::): (KJS::ImmediateNumberNode::): (KJS::AddNode::precedence):
  • kjs/nodes2string.cpp: (KJS::NumberNode::streamTo):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/nodes.h

    r27501 r27589  
    66 *  Copyright (C) 2007 Cameron Zwarich ([email protected])
    77 *  Copyright (C) 2007 Maks Orlovich
     8 *  Copyright (C) 2007 Eric Seidel <[email protected]>
    89 *
    910 *  This library is free software; you can redistribute it and/or
     
    117118    virtual ~Node();
    118119
    119     virtual JSValue *evaluate(ExecState *exec) KJS_FAST_CALL = 0;
     120    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
     121    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    120122    UString toString() const KJS_FAST_CALL;
    121123    int lineNo() const KJS_FAST_CALL { return m_line; }
     
    126128
    127129    virtual bool isNumber() const KJS_FAST_CALL { return false; }
    128     virtual bool isImmediateValue() const KJS_FAST_CALL { return false; }
    129130    virtual bool isLocation() const KJS_FAST_CALL { return false; }
    130131    virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
     
    210211  class NumberNode : public Node {
    211212  public:
    212     NumberNode(double v) KJS_FAST_CALL : val(v) {}
    213     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     213    NumberNode(double v) KJS_FAST_CALL : m_double(v) {}
     214    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     215    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    214216    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    215217    virtual Precedence precedence() const { return PrecPrimary; }
    216218
    217219    virtual bool isNumber() const KJS_FAST_CALL { return true; }
    218     double value() const KJS_FAST_CALL { return val; }
    219     void setValue(double v) KJS_FAST_CALL { val = v; }
    220   private:
    221     double val;
     220    double value() const KJS_FAST_CALL { return m_double; }
     221    virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
     222  protected:
     223    double m_double;
    222224  };
    223225 
    224   class ImmediateNumberNode : public Node {
    225   public:
    226       ImmediateNumberNode(JSValue* v) KJS_FAST_CALL : m_value(v) {}
    227       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    228       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    229       virtual Precedence precedence() const { return PrecPrimary; }
     226  class ImmediateNumberNode : public NumberNode {
     227  public:
     228      ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::fromDouble(d)); }
     229      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    230230     
    231       virtual bool isImmediateValue() const KJS_FAST_CALL { return true; }
    232       double value() const KJS_FAST_CALL { return JSImmediate::toDouble(m_value); }
    233       void setValue(double v) KJS_FAST_CALL { m_value = JSImmediate::fromDouble(v); ASSERT(m_value); }
     231      virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::fromDouble(d); ASSERT(m_value); }
    234232  private:
    235233      JSValue* m_value;
     
    239237  public:
    240238    StringNode(const UString *v) KJS_FAST_CALL { value = *v; }
    241     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     239    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     240    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    242241    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    243242    virtual Precedence precedence() const { return PrecPrimary; }
     
    304303    }
    305304    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     305    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     306  private:
     307    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
    306308  };
    307309
     
    390392    BracketAccessorNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
    391393    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    392     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     394    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     395    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    393396    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    394397    virtual Precedence precedence() const { return PrecMember; }
     
    400403
    401404  private:
     405    ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
    402406    RefPtr<Node> expr1;
    403407    RefPtr<Node> expr2;
     
    950954    NegateNode(Node *e) KJS_FAST_CALL : expr(e) {}
    951955    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    952     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     956    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     957    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    953958    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    954959    virtual Precedence precedence() const { return PrecUnary; }
     
    983988      MultNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    984989      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    985       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     990      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     991      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    986992      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    987993      virtual Precedence precedence() const { return PrecMultiplicitave; }
    988994  private:
     995      ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
    989996      RefPtr<Node> term1;
    990997      RefPtr<Node> term2;
     
    9951002      DivNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    9961003      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    997       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1004      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1005      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    9981006      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    9991007      virtual Precedence precedence() const { return PrecMultiplicitave; }
    10001008  private:
     1009      ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
    10011010      RefPtr<Node> term1;
    10021011      RefPtr<Node> term2;
     
    10071016      ModNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    10081017      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1009       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1018      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1019      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    10101020      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    10111021      virtual Precedence precedence() const { return PrecMultiplicitave; }
    10121022  private:
     1023      ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
    10131024      RefPtr<Node> term1;
    10141025      RefPtr<Node> term2;
     
    10191030    AddNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    10201031    virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1021     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
    1022     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    1023       virtual Precedence precedence() const { return PrecAdditive; }
     1032    virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1033    virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
     1034    virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     1035    virtual Precedence precedence() const { return PrecAdditive; }
    10241036  private:
    10251037    RefPtr<Node> term1;
     
    10311043      SubNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
    10321044      virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
    1033       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1045      virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
     1046      virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
    10341047      virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
    10351048      virtual Precedence precedence() const { return PrecAdditive; }
    10361049  private:
     1050      ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
    10371051      RefPtr<Node> term1;
    10381052      RefPtr<Node> term2;
Note: See TracChangeset for help on using the changeset viewer.