Reviewed by Eric Seidel.
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2007 00:06:43 +0000 (00:06 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2007 00:06:43 +0000 (00:06 +0000)
        Added toJSNumber, a fast path for converting a JSValue to a JS number,
        and deployed it in postfix expressions. In the fast case this
        eliminates a call to jsNumber.

        0.4% speedup on SunSpider.

        * ChangeLog:
        * kjs/nodes.cpp:
        (KJS::PostIncResolveNode::evaluate):
        (KJS::PostIncLocalVarNode::evaluate):
        (KJS::PostDecResolveNode::evaluate):
        (KJS::PostDecLocalVarNode::evaluate):
        (KJS::PostIncBracketNode::evaluate):
        (KJS::PostDecBracketNode::evaluate):
        (KJS::PostIncDotNode::evaluate):
        (KJS::PostDecDotNode::evaluate):
        (KJS::UnaryPlusNode::evaluate):
        * kjs/value.h:
        (KJS::JSValue::toJSNumber):

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

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/value.h

index 791bfe15aa9adb735af855a3f3df0c3c758f7078..4f36019ac6ce831d4bf40be4dd8f00267d154445 100644 (file)
@@ -1,3 +1,27 @@
+2007-11-06  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Eric Seidel.
+        
+        Added toJSNumber, a fast path for converting a JSValue to a JS number,
+        and deployed it in postfix expressions. In the fast case this 
+        eliminates a call to jsNumber.
+        
+        0.4% speedup on SunSpider.
+
+        * ChangeLog:
+        * kjs/nodes.cpp:
+        (KJS::PostIncResolveNode::evaluate):
+        (KJS::PostIncLocalVarNode::evaluate):
+        (KJS::PostDecResolveNode::evaluate):
+        (KJS::PostDecLocalVarNode::evaluate):
+        (KJS::PostIncBracketNode::evaluate):
+        (KJS::PostDecBracketNode::evaluate):
+        (KJS::PostIncDotNode::evaluate):
+        (KJS::PostDecDotNode::evaluate):
+        (KJS::UnaryPlusNode::evaluate):
+        * kjs/value.h:
+        (KJS::JSValue::toJSNumber):
+
 2007-11-06  Darin Adler  <darin@apple.com>
 
         Reviewed by Maciej.
index 771056209ecf2d2abbca1499438a9130a70df1ec..e236b4fc283416785e638bf98abec8c7145bdbd9 100644 (file)
@@ -923,11 +923,9 @@ JSValue *PostIncResolveNode::evaluate(ExecState *exec)
   do { 
     base = *iter;
     if (base->getPropertySlot(exec, m_ident, slot)) {
-        JSValue *v = slot.getValue(exec, base, m_ident);
-
-        double n = v->toNumber(exec);
-        base->put(exec, m_ident, jsNumber(n + 1));
-        return jsNumber(n);
+        JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
+        base->put(exec, m_ident, jsNumber(v->toNumber(exec) + 1));
+        return v;
     }
 
     ++iter;
@@ -942,9 +940,9 @@ JSValue* PostIncLocalVarNode::evaluate(ExecState* exec)
     ASSERT(static_cast<ActivationImp*>(exec->variableObject()) == exec->scopeChain().top());
 
     JSValue** slot = &exec->localStorage()[index].value;
-    double n = (*slot)->toNumber(exec);
-    *slot = jsNumber(n + 1);
-    return jsNumber(n);
+    JSValue* v = (*slot)->toJSNumber(exec);
+    *slot = jsNumber(v->toNumber(exec) + 1);
+    return v;
 }
 
 
@@ -973,11 +971,9 @@ JSValue *PostDecResolveNode::evaluate(ExecState *exec)
   do { 
     base = *iter;
     if (base->getPropertySlot(exec, m_ident, slot)) {
-        JSValue *v = slot.getValue(exec, base, m_ident);
-
-        double n = v->toNumber(exec);
-        base->put(exec, m_ident, jsNumber(n - 1));
-        return jsNumber(n);
+        JSValue* v = slot.getValue(exec, base, m_ident)->toJSNumber(exec);
+        base->put(exec, m_ident, jsNumber(v->toNumber(exec) - 1));
+        return v;
     }
 
     ++iter;
@@ -992,9 +988,9 @@ JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
     ASSERT(static_cast<ActivationImp*>(exec->variableObject()) == exec->scopeChain().top());
 
     JSValue** slot = &exec->localStorage()[index].value;
-    double n = (*slot)->toNumber(exec);
-    *slot = jsNumber(n - 1);
-    return jsNumber(n);
+    JSValue* v = (*slot)->toJSNumber(exec);
+    *slot = jsNumber(v->toNumber(exec) - 1);
+    return v;
 }
 
 // ------------------------------ PostfixBracketNode ----------------------------------
@@ -1020,11 +1016,10 @@ JSValue *PostIncBracketNode::evaluate(ExecState *exec)
     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
     KJS_CHECKEXCEPTIONVALUE
 
-    double n = v->toNumber(exec);
-
-    base->put(exec, propertyIndex, jsNumber(n + 1));
+    JSValue* v2 = v->toJSNumber(exec);
+    base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) + 1));
         
-    return jsNumber(n);
+    return v2;
   }
 
   Identifier propertyName(subscript->toString(exec));
@@ -1032,11 +1027,9 @@ JSValue *PostIncBracketNode::evaluate(ExecState *exec)
   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
   KJS_CHECKEXCEPTIONVALUE
 
-  double n = v->toNumber(exec);
-  
-  base->put(exec, propertyName, jsNumber(n + 1));
-        
-  return jsNumber(n);
+  JSValue* v2 = v->toJSNumber(exec);
+  base->put(exec, propertyName, jsNumber(v2->toNumber(exec) + 1));
+  return v2;
 }
 
 JSValue *PostDecBracketNode::evaluate(ExecState *exec)
@@ -1054,11 +1047,9 @@ JSValue *PostDecBracketNode::evaluate(ExecState *exec)
     JSValue *v = base->getPropertySlot(exec, propertyIndex, slot) ? slot.getValue(exec, base, propertyIndex) : jsUndefined();
     KJS_CHECKEXCEPTIONVALUE
 
-    double n = v->toNumber(exec);
-
-    base->put(exec, propertyIndex, jsNumber(n - 1));
-        
-    return jsNumber(n);
+    JSValue* v2 = v->toJSNumber(exec);
+    base->put(exec, propertyIndex, jsNumber(v2->toNumber(exec) - 1));
+    return v2;
   }
 
   Identifier propertyName(subscript->toString(exec));
@@ -1066,11 +1057,9 @@ JSValue *PostDecBracketNode::evaluate(ExecState *exec)
   JSValue *v = base->getPropertySlot(exec, propertyName, slot) ? slot.getValue(exec, base, propertyName) : jsUndefined();
   KJS_CHECKEXCEPTIONVALUE
 
-  double n = v->toNumber(exec);
-  
-  base->put(exec, propertyName, jsNumber(n - 1));
-        
-  return jsNumber(n);
+  JSValue* v2 = v->toJSNumber(exec);
+  base->put(exec, propertyName, jsNumber(v2->toNumber(exec) - 1));
+  return v2;
 }
 
 // ------------------------------ PostfixDotNode ----------------------------------
@@ -1090,11 +1079,9 @@ JSValue *PostIncDotNode::evaluate(ExecState *exec)
   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
   KJS_CHECKEXCEPTIONVALUE
 
-  double n = v->toNumber(exec);
-  
-  base->put(exec, m_ident, jsNumber(n + 1));
-        
-  return jsNumber(n);
+  JSValue* v2 = v->toJSNumber(exec);
+  base->put(exec, m_ident, jsNumber(v2->toNumber(exec) + 1));
+  return v2;
 }
 
 JSValue *PostDecDotNode::evaluate(ExecState *exec)
@@ -1107,11 +1094,9 @@ JSValue *PostDecDotNode::evaluate(ExecState *exec)
   JSValue *v = base->getPropertySlot(exec, m_ident, slot) ? slot.getValue(exec, base, m_ident) : jsUndefined();
   KJS_CHECKEXCEPTIONVALUE
 
-  double n = v->toNumber(exec);
-  
-  base->put(exec, m_ident, jsNumber(n - 1));
-        
-  return jsNumber(n);
+  JSValue* v2 = v->toJSNumber(exec);
+  base->put(exec, m_ident, jsNumber(v2->toNumber(exec) - 1));
+  return v2;
 }
 
 // ------------------------------ PostfixErrorNode -----------------------------------
@@ -1561,7 +1546,7 @@ JSValue *UnaryPlusNode::evaluate(ExecState *exec)
   JSValue *v = expr->evaluate(exec);
   KJS_CHECKEXCEPTIONVALUE
 
-  return jsNumber(v->toNumber(exec));
+  return v->toJSNumber(exec);
 }
 
 // ------------------------------ NegateNode -----------------------------------
index c50581be246f29a73befd627aace21462d2295d0..c4276f225e9957c5b57e78b03e070ee672e1f3f9 100644 (file)
@@ -85,6 +85,7 @@ public:
 
     bool toBoolean(ExecState *exec) const;
     double toNumber(ExecState *exec) const;
+    JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
     UString toString(ExecState *exec) const;
     JSObject *toObject(ExecState *exec) const;
 
@@ -391,6 +392,11 @@ ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const
     return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->toNumber(exec);
 }
 
+ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
+{
+    return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(this->toNumber(exec));
+}
+
 inline UString JSValue::toString(ExecState *exec) const
 {
     return JSImmediate::isImmediate(this) ? JSImmediate::toString(this) : asCell()->toString(exec);