Commit 8e708701 authored by ap@webkit.org's avatar ap@webkit.org

Reviewed by Maciej.

        Based on a patch by Oliver Hunt.

        https://bugs.webkit.org/show_bug.cgi?id=19180
        speed up SunSpider by optimizing immediate number cases

        1.4% speedup on SunSpider.

        * VM/Machine.cpp:
        (KJS::Machine::privateExecute):
        * kjs/JSImmediate.h:
        (KJS::JSImmediate::incImmediateNumber):
        (KJS::JSImmediate::decImmediateNumber):
        Added fast paths for ++ and --.

        (KJS::JSImmediate::canDoFastAdditiveOperations): Corrected a comment.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34171 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 2cc75ff0
2008-05-28 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Maciej.
Based on a patch by Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=19180
speed up SunSpider by optimizing immediate number cases
1.4% speedup on SunSpider.
* VM/Machine.cpp:
(KJS::Machine::privateExecute):
* kjs/JSImmediate.h:
(KJS::JSImmediate::incImmediateNumber):
(KJS::JSImmediate::decImmediateNumber):
Added fast paths for ++ and --.
(KJS::JSImmediate::canDoFastAdditiveOperations): Corrected a comment.
2008-05-28 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
......
......@@ -1077,7 +1077,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
back in register srcDst.
*/
int srcDst = (++vPC)->u.operand;
JSValue* result = jsNumber(r[srcDst].u.jsValue->toNumber(exec) + 1);
JSValue* v = r[srcDst].u.jsValue;
JSValue* result;
if (JSImmediate::canDoFastAdditiveOperations(v))
result = JSImmediate::incImmediateNumber(v);
else
result = jsNumber(v->toNumber(exec) + 1);
VM_CHECK_EXCEPTION();
r[srcDst].u.jsValue = result;
......@@ -1091,7 +1096,12 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
back in register srcDst.
*/
int srcDst = (++vPC)->u.operand;
JSValue* result = jsNumber(r[srcDst].u.jsValue->toNumber(exec) - 1);
JSValue* v = r[srcDst].u.jsValue;
JSValue* result;
if (JSImmediate::canDoFastAdditiveOperations(v))
result = JSImmediate::decImmediateNumber(v);
else
result = jsNumber(v->toNumber(exec) - 1);
VM_CHECK_EXCEPTION();
r[srcDst].u.jsValue = result;
......@@ -1107,11 +1117,20 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
*/
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
JSValue* number = r[srcDst].u.jsValue->toJSNumber(exec);
JSValue* v = r[srcDst].u.jsValue;
JSValue* result;
JSValue* number;
if (JSImmediate::canDoFastAdditiveOperations(v)) {
number = v;
result = JSImmediate::incImmediateNumber(v);
} else {
number = r[srcDst].u.jsValue->toJSNumber(exec);
result = jsNumber(number->uncheckedGetNumber() + 1);
}
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = number;
r[srcDst].u.jsValue = jsNumber(number->uncheckedGetNumber() + 1);
r[srcDst].u.jsValue = result;
++vPC;
NEXT_OPCODE;
......@@ -1125,11 +1144,20 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
*/
int dst = (++vPC)->u.operand;
int srcDst = (++vPC)->u.operand;
JSValue* number = r[srcDst].u.jsValue->toJSNumber(exec);
JSValue* v = r[srcDst].u.jsValue;
JSValue* result;
JSValue* number;
if (JSImmediate::canDoFastAdditiveOperations(v)) {
number = v;
result = JSImmediate::decImmediateNumber(v);
} else {
number = r[srcDst].u.jsValue->toJSNumber(exec);
result = jsNumber(number->uncheckedGetNumber() - 1);
}
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = number;
r[srcDst].u.jsValue = jsNumber(number->uncheckedGetNumber() - 1);
r[srcDst].u.jsValue = result;
++vPC;
NEXT_OPCODE;
......
......@@ -120,7 +120,7 @@ public:
static ALWAYS_INLINE bool canDoFastAdditiveOperations(const JSValue* v)
{
// Number is positive and an operation involving two of these can't overflow.
// Number is non-negative and an operation involving two of these can't overflow.
// Checking for allowed negative numbers takes more time than it's worth on SunSpider.
return (reinterpret_cast<uintptr_t>(v) & (NumberType + (3 << 30))) == NumberType;
}
......@@ -139,6 +139,18 @@ public:
return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v1) - (reinterpret_cast<uintptr_t>(v2) & ~NumberType));
}
static ALWAYS_INLINE JSValue* incImmediateNumber(const JSValue* v)
{
ASSERT(canDoFastAdditiveOperations(v));
return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v) + TagMask + 1);
}
static ALWAYS_INLINE JSValue* decImmediateNumber(const JSValue* v)
{
ASSERT(canDoFastAdditiveOperations(v));
return reinterpret_cast<JSValue*>(reinterpret_cast<uintptr_t>(v) - (TagMask + 1));
}
static double toDouble(const JSValue*);
static bool toBoolean(const JSValue*);
static JSObject* toObject(const JSValue*, ExecState*);
......
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