2008-06-14 Cameron Zwarich <cwzwarich@uwaterloo.ca>
authorcwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Jun 2008 05:24:21 +0000 (05:24 +0000)
committercwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 15 Jun 2008 05:24:21 +0000 (05:24 +0000)
        Reviewed by Maciej.

        Make code generation not use a temporary for the left-hand side of an
        expression if the right-hand side is a local variable.

        * VM/CodeGenerator.cpp:
        (KJS::CodeGenerator::isLocal):
        * VM/CodeGenerator.h:
        (KJS::CodeGenerator::leftHandSideNeedsCopy):
        (KJS::CodeGenerator::emitNodeForLeftHandSide):
        * kjs/nodes.cpp:
        (KJS::ResolveNode::isPure):
        (KJS::BracketAccessorNode::emitCode):
        (KJS::AddNode::emitCode):
        (KJS::SubNode::emitCode):
        (KJS::ReadModifyResolveNode::emitCode):
        (KJS::AssignDotNode::emitCode):
        (KJS::ReadModifyDotNode::emitCode):
        (KJS::AssignBracketNode::emitCode):
        (KJS::ReadModifyBracketNode::emitCode):
        * kjs/nodes.h:
        (KJS::ExpressionNode::):
        (KJS::BooleanNode::):
        (KJS::NumberNode::):
        (KJS::StringNode::):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@34555 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/VM/CodeGenerator.cpp
JavaScriptCore/VM/CodeGenerator.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h

index 5eb542f..f59b4a9 100644 (file)
@@ -1,3 +1,31 @@
+2008-06-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Maciej.
+
+        Make code generation not use a temporary for the left-hand side of an
+        expression if the right-hand side is a local variable.
+
+        * VM/CodeGenerator.cpp:
+        (KJS::CodeGenerator::isLocal):
+        * VM/CodeGenerator.h:
+        (KJS::CodeGenerator::leftHandSideNeedsCopy):
+        (KJS::CodeGenerator::emitNodeForLeftHandSide):
+        * kjs/nodes.cpp:
+        (KJS::ResolveNode::isPure):
+        (KJS::BracketAccessorNode::emitCode):
+        (KJS::AddNode::emitCode):
+        (KJS::SubNode::emitCode):
+        (KJS::ReadModifyResolveNode::emitCode):
+        (KJS::AssignDotNode::emitCode):
+        (KJS::ReadModifyDotNode::emitCode):
+        (KJS::AssignBracketNode::emitCode):
+        (KJS::ReadModifyBracketNode::emitCode):
+        * kjs/nodes.h:
+        (KJS::ExpressionNode::):
+        (KJS::BooleanNode::):
+        (KJS::NumberNode::):
+        (KJS::StringNode::):
+
 2008-06-14  Darin Adler  <darin@apple.com>
 
         Reviewed by Sam.
index b560ce7..096b619 100644 (file)
@@ -343,6 +343,14 @@ RegisterID* CodeGenerator::registerForLocalConstInit(const Identifier& ident)
     return &m_locals[localsIndex(entry.getIndex())];
 }
 
+bool CodeGenerator::isLocal(const Identifier& ident)
+{
+    if (ident == m_propertyNames->thisIdentifier)
+        return true;
+    
+    return shouldOptimizeLocals() && symbolTable().contains(ident.ustring().rep());
+}
+
 bool CodeGenerator::isLocalConstant(const Identifier& ident)
 {
     return symbolTable().get(ident.ustring().rep()).isReadOnly();
index ac61d3c..8e2cbc6 100644 (file)
@@ -108,6 +108,7 @@ namespace KJS {
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
 
+        bool isLocal(const Identifier&);
         bool isLocalConstant(const Identifier&);
 
         // Returns the next available temporary register. Registers returned by
@@ -171,14 +172,14 @@ namespace KJS {
             return emitNode(0, n);
         }
 
-        ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsConstant)
+        ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsPure)
         {
-            return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain || rightHasAssignments) && !rightIsConstant;
+            return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain || rightHasAssignments) && !rightIsPure;
         }
 
-        ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsConstant)
+        ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsPure)
         {
-            if (leftHandSideNeedsCopy(rightHasAssignments, rightIsConstant)) {
+            if (leftHandSideNeedsCopy(rightHasAssignments, rightIsPure)) {
                 PassRefPtr<RegisterID> dst = newTemporary();
                 emitNode(dst.get(), n);
                 return dst;
index d829011..3729ecd 100644 (file)
@@ -327,6 +327,11 @@ RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 // ------------------------------ ResolveNode ----------------------------------
 
+bool ResolveNode::isPure(CodeGenerator& generator) const
+{
+    return generator.isLocal(m_ident);
+}
+
 RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
     if (RegisterID* local = generator.registerForLocal(m_ident))
@@ -402,7 +407,7 @@ RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst
 
 RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript.get()->isConstant());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript.get()->isPure(generator));
     RegisterID* property = generator.emitNode(m_subscript.get());
 
     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
@@ -823,14 +828,14 @@ RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2.get()->isConstant());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2.get()->isPure(generator));
     RegisterID* src2 = generator.emitNode(m_term2.get());
     return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
 }
 
 RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2.get()->isConstant());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_term1.get(), m_rightHasAssignments, m_term2.get()->isPure(generator));
     RegisterID* src2 = generator.emitNode(m_term2.get());
     return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
 }
@@ -1048,7 +1053,7 @@ RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID
             return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
         }
         
-        if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right.get()->isConstant())) {
+        if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right.get()->isPure(generator))) {
             RefPtr<RegisterID> result = generator.newTemporary();
             generator.emitMove(result.get(), local);
             RegisterID* src2 = generator.emitNode(m_right.get());
@@ -1108,7 +1113,7 @@ RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
 RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isConstant());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isPure(generator));
     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
     RegisterID* result = generator.emitNode(value.get(), m_right.get());
     generator.emitPutById(base.get(), m_ident, result);
@@ -1119,7 +1124,7 @@ RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isConstant());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isPure(generator));
     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
     RegisterID* change = generator.emitNode(m_right.get());
     RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
@@ -1137,8 +1142,8 @@ RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
 
 RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript.get()->isConstant() && m_right.get()->isConstant());
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right.get()->isConstant());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript.get()->isPure(generator) && m_right.get()->isPure(generator));
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right.get()->isPure(generator));
     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
     RegisterID* result = generator.emitNode(value.get(), m_right.get());
     generator.emitPutByVal(base.get(), property.get(), result);
@@ -1147,8 +1152,8 @@ RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* ds
 
 RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript.get()->isConstant() && m_right.get()->isConstant());
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right.get()->isConstant());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript.get()->isPure(generator) && m_right.get()->isPure(generator));
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right.get()->isPure(generator));
 
     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
     RegisterID* change = generator.emitNode(m_right.get());
index 82c5120..9e08b3c 100644 (file)
@@ -208,7 +208,7 @@ namespace KJS {
         }
 
         virtual bool isNumber() const KJS_FAST_CALL { return false; }
-        virtual bool isConstant() const KJS_FAST_CALL { return false; }        
+        virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return false; }        
         virtual bool isLocation() const KJS_FAST_CALL { return false; }
         virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
@@ -261,7 +261,7 @@ namespace KJS {
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual bool isConstant() const KJS_FAST_CALL { return true; }
+        virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -283,7 +283,7 @@ namespace KJS {
         virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
 
         virtual bool isNumber() const KJS_FAST_CALL { return true; }
-        virtual bool isConstant() const KJS_FAST_CALL { return true; }
+        virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
         double value() const KJS_FAST_CALL { return m_double; }
         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
 
@@ -316,7 +316,7 @@ namespace KJS {
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual bool isConstant() const KJS_FAST_CALL { return true; }
+        virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -371,6 +371,7 @@ namespace KJS {
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
+        virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL;
         virtual bool isLocation() const KJS_FAST_CALL { return true; }
         virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }