2008-06-13 Cameron Zwarich <cwzwarich@uwaterloo.ca>
authorcwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jun 2008 04:40:45 +0000 (04:40 +0000)
committercwzwarich@webkit.org <cwzwarich@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 14 Jun 2008 04:40:45 +0000 (04:40 +0000)
        Reviewed by Maciej.

        Eliminate the use of temporaries to store the left hand side of an
        expression when the right hand side is a constant. This slightly
        improves the generated bytecode for a few SunSpider tests, but it is
        mostly in preparation for fixing

        Bug 19484: More instructions needs to use temporary registers
        <https://bugs.webkit.org/show_bug.cgi?id=19484>

        * VM/CodeGenerator.h:
        (KJS::CodeGenerator::leftHandSideNeedsCopy):
        (KJS::CodeGenerator::emitNodeForLeftHandSide):
        * kjs/nodes.cpp:
        (KJS::BracketAccessorNode::emitCode):
        (KJS::ReadModifyResolveNode::emitCode):
        (KJS::AssignDotNode::emitCode):
        (KJS::ReadModifyDotNode::emitCode):
        (KJS::AssignBracketNode::emitCode):
        (KJS::ReadModifyBracketNode::emitCode):
        * kjs/nodes.h:
        (KJS::ExpressionNode::):
        (KJS::FalseNode::):
        (KJS::TrueNode::):
        (KJS::NumberNode::):
        (KJS::StringNode::):

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

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

index ced8a12..82dd577 100644 (file)
@@ -1,3 +1,32 @@
+2008-06-13  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
+
+        Reviewed by Maciej.
+
+        Eliminate the use of temporaries to store the left hand side of an
+        expression when the right hand side is a constant. This slightly
+        improves the generated bytecode for a few SunSpider tests, but it is
+        mostly in preparation for fixing
+
+        Bug 19484: More instructions needs to use temporary registers
+        <https://bugs.webkit.org/show_bug.cgi?id=19484>
+
+        * VM/CodeGenerator.h:
+        (KJS::CodeGenerator::leftHandSideNeedsCopy):
+        (KJS::CodeGenerator::emitNodeForLeftHandSide):
+        * kjs/nodes.cpp:
+        (KJS::BracketAccessorNode::emitCode):
+        (KJS::ReadModifyResolveNode::emitCode):
+        (KJS::AssignDotNode::emitCode):
+        (KJS::ReadModifyDotNode::emitCode):
+        (KJS::AssignBracketNode::emitCode):
+        (KJS::ReadModifyBracketNode::emitCode):
+        * kjs/nodes.h:
+        (KJS::ExpressionNode::):
+        (KJS::FalseNode::):
+        (KJS::TrueNode::):
+        (KJS::NumberNode::):
+        (KJS::StringNode::):
+
 2008-06-13  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Oliver.
index 2b2d83e..ac61d3c 100644 (file)
@@ -171,14 +171,14 @@ namespace KJS {
             return emitNode(0, n);
         }
 
-        ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments)
+        ALWAYS_INLINE bool leftHandSideNeedsCopy(bool rightHasAssignments, bool rightIsConstant)
         {
-            return m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain || rightHasAssignments;
+            return (m_codeType != FunctionCode || m_codeBlock->needsFullScopeChain || rightHasAssignments) && !rightIsConstant;
         }
 
-        ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments)
+        ALWAYS_INLINE PassRefPtr<RegisterID> emitNodeForLeftHandSide(ExpressionNode* n, bool rightHasAssignments, bool rightIsConstant)
         {
-            if (leftHandSideNeedsCopy(rightHasAssignments)) {
+            if (leftHandSideNeedsCopy(rightHasAssignments, rightIsConstant)) {
                 PassRefPtr<RegisterID> dst = newTemporary();
                 emitNode(dst.get(), n);
                 return dst;
index 8639166..a9a3ae6 100644 (file)
@@ -409,7 +409,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);
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript.get()->isConstant());
     RegisterID* property = generator.emitNode(m_subscript.get());
 
     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
@@ -1055,7 +1055,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()->isNumber()) {
+        if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right.get()->isConstant())) {
             RefPtr<RegisterID> result = generator.newTemporary();
             generator.emitMove(result.get(), local);
             RegisterID* src2 = generator.emitNode(m_right.get());
@@ -1115,7 +1115,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);
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isConstant());
     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
     RegisterID* result = generator.emitNode(value.get(), m_right.get());
     generator.emitPutById(base.get(), m_ident, result);
@@ -1126,7 +1126,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);
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right.get()->isConstant());
     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);
@@ -1144,8 +1144,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);
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
+    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> value = generator.destinationForAssignResult(dst);
     RegisterID* result = generator.emitNode(value.get(), m_right.get());
     generator.emitPutByVal(base.get(), property.get(), result);
@@ -1154,8 +1154,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);
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
+    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> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
     RegisterID* change = generator.emitNode(m_right.get());
index 19a53ab..cf2b4ec 100644 (file)
@@ -208,6 +208,7 @@ namespace KJS {
         }
 
         virtual bool isNumber() const KJS_FAST_CALL { return false; }
+        virtual bool isConstant() 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; }
@@ -259,6 +260,7 @@ namespace KJS {
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
+        virtual bool isConstant() const KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -272,6 +274,7 @@ namespace KJS {
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
+        virtual bool isConstant() const KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -301,6 +304,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; }
         double value() const KJS_FAST_CALL { return m_double; }
         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
 
@@ -333,6 +337,7 @@ namespace KJS {
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
+        virtual bool isConstant() const KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }