Commit dcb807d9 authored by eric@webkit.org's avatar eric@webkit.org

2007-11-12 Eric Seidel <eric@webkit.org>

        Reviewed by Oliver.

        Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
        Fix a few missing evaluateToBoolean methods
        Deploy all evaluateTo* functions to more nodes to avoid slowdowns
        http://bugs.webkit.org/show_bug.cgi?id=15950

        SunSpider claims this is at least a 1.4% speedup.

        * kjs/JSImmediate.h:
        (KJS::JSImmediate::getTruncatedInt32):
        (KJS::JSImmediate::toDouble):
        (KJS::JSImmediate::getUInt32):
        * kjs/nodes.cpp:
        (KJS::ExpressionNode::evaluateToNumber):
        (KJS::ExpressionNode::evaluateToInt32):
        (KJS::ExpressionNode::evaluateToUInt32):
        (KJS::NumberNode::evaluateToInt32):
        (KJS::NumberNode::evaluateToUInt32):
        (KJS::ImmediateNumberNode::evaluateToInt32):
        (KJS::ImmediateNumberNode::evaluateToUInt32):
        (KJS::ResolveNode::evaluate):
        (KJS::ResolveNode::evaluateToNumber):
        (KJS::ResolveNode::evaluateToBoolean):
        (KJS::ResolveNode::evaluateToInt32):
        (KJS::ResolveNode::evaluateToUInt32):
        (KJS::LocalVarAccessNode::evaluateToInt32):
        (KJS::LocalVarAccessNode::evaluateToUInt32):
        (KJS::BracketAccessorNode::evaluateToNumber):
        (KJS::BracketAccessorNode::evaluateToBoolean):
        (KJS::BracketAccessorNode::evaluateToInt32):
        (KJS::BracketAccessorNode::evaluateToUInt32):
        (KJS::DotAccessorNode::inlineEvaluate):
        (KJS::DotAccessorNode::evaluate):
        (KJS::DotAccessorNode::evaluateToNumber):
        (KJS::DotAccessorNode::evaluateToBoolean):
        (KJS::DotAccessorNode::evaluateToInt32):
        (KJS::DotAccessorNode::evaluateToUInt32):
        (KJS::NewExprNode::inlineEvaluate):
        (KJS::NewExprNode::evaluate):
        (KJS::NewExprNode::evaluateToNumber):
        (KJS::NewExprNode::evaluateToBoolean):
        (KJS::NewExprNode::evaluateToInt32):
        (KJS::NewExprNode::evaluateToUInt32):
        (KJS::FunctionCallResolveNode::inlineEvaluate):
        (KJS::FunctionCallResolveNode::evaluate):
        (KJS::FunctionCallResolveNode::evaluateToNumber):
        (KJS::FunctionCallResolveNode::evaluateToBoolean):
        (KJS::FunctionCallResolveNode::evaluateToInt32):
        (KJS::FunctionCallResolveNode::evaluateToUInt32):
        (KJS::LocalVarFunctionCallNode::evaluate):
        (KJS::LocalVarFunctionCallNode::evaluateToNumber):
        (KJS::LocalVarFunctionCallNode::evaluateToBoolean):
        (KJS::LocalVarFunctionCallNode::evaluateToInt32):
        (KJS::LocalVarFunctionCallNode::evaluateToUInt32):
        (KJS::FunctionCallDotNode::evaluate):
        (KJS::FunctionCallDotNode::evaluateToNumber):
        (KJS::FunctionCallDotNode::evaluateToBoolean):
        (KJS::FunctionCallDotNode::evaluateToInt32):
        (KJS::FunctionCallDotNode::evaluateToUInt32):
        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
        (KJS::PostDecLocalVarNode::evaluateToNumber):
        (KJS::PostDecLocalVarNode::evaluateToBoolean):
        (KJS::PostDecLocalVarNode::evaluateToInt32):
        (KJS::PostDecLocalVarNode::evaluateToUInt32):
        (KJS::typeStringForValue):
        (KJS::UnaryPlusNode::evaluate):
        (KJS::UnaryPlusNode::evaluateToBoolean):
        (KJS::UnaryPlusNode::evaluateToNumber):
        (KJS::UnaryPlusNode::evaluateToInt32):
        (KJS::BitwiseNotNode::inlineEvaluateToInt32):
        (KJS::BitwiseNotNode::evaluate):
        (KJS::BitwiseNotNode::evaluateToNumber):
        (KJS::BitwiseNotNode::evaluateToBoolean):
        (KJS::BitwiseNotNode::evaluateToInt32):
        (KJS::MultNode::evaluateToBoolean):
        (KJS::MultNode::evaluateToInt32):
        (KJS::MultNode::evaluateToUInt32):
        (KJS::DivNode::evaluateToInt32):
        (KJS::DivNode::evaluateToUInt32):
        (KJS::ModNode::evaluateToBoolean):
        (KJS::ModNode::evaluateToInt32):
        (KJS::ModNode::evaluateToUInt32):
        (KJS::AddNode::evaluateToNumber):
        (KJS::AddNode::evaluateToInt32):
        (KJS::AddNode::evaluateToUInt32):
        (KJS::AddNumbersNode::evaluateToInt32):
        (KJS::AddNumbersNode::evaluateToUInt32):
        (KJS::SubNode::evaluateToInt32):
        (KJS::SubNode::evaluateToUInt32):
        (KJS::LeftShiftNode::inlineEvaluateToInt32):
        (KJS::LeftShiftNode::evaluate):
        (KJS::LeftShiftNode::evaluateToNumber):
        (KJS::LeftShiftNode::evaluateToInt32):
        (KJS::RightShiftNode::inlineEvaluateToInt32):
        (KJS::RightShiftNode::evaluate):
        (KJS::RightShiftNode::evaluateToNumber):
        (KJS::RightShiftNode::evaluateToInt32):
        (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
        (KJS::UnsignedRightShiftNode::evaluate):
        (KJS::UnsignedRightShiftNode::evaluateToNumber):
        (KJS::UnsignedRightShiftNode::evaluateToInt32):
        (KJS::LessNode::inlineEvaluateToBoolean):
        (KJS::LessNode::evaluate):
        (KJS::LessNode::evaluateToBoolean):
        (KJS::LessNumbersNode::inlineEvaluateToBoolean):
        (KJS::LessNumbersNode::evaluate):
        (KJS::LessNumbersNode::evaluateToBoolean):
        (KJS::LessStringsNode::inlineEvaluateToBoolean):
        (KJS::LessStringsNode::evaluate):
        (KJS::BitAndNode::evaluate):
        (KJS::BitAndNode::inlineEvaluateToInt32):
        (KJS::BitAndNode::evaluateToNumber):
        (KJS::BitAndNode::evaluateToBoolean):
        (KJS::BitAndNode::evaluateToInt32):
        (KJS::BitXOrNode::inlineEvaluateToInt32):
        (KJS::BitXOrNode::evaluate):
        (KJS::BitXOrNode::evaluateToNumber):
        (KJS::BitXOrNode::evaluateToBoolean):
        (KJS::BitXOrNode::evaluateToInt32):
        (KJS::BitOrNode::inlineEvaluateToInt32):
        (KJS::BitOrNode::evaluate):
        (KJS::BitOrNode::evaluateToNumber):
        (KJS::BitOrNode::evaluateToBoolean):
        (KJS::BitOrNode::evaluateToInt32):
        (KJS::ConditionalNode::evaluateToNumber):
        (KJS::ConditionalNode::evaluateToInt32):
        (KJS::ConditionalNode::evaluateToUInt32):
        (KJS::valueForReadModifyAssignment):
        (KJS::AssignExprNode::evaluate):
        (KJS::AssignExprNode::evaluateToBoolean):
        (KJS::AssignExprNode::evaluateToNumber):
        (KJS::AssignExprNode::evaluateToInt32):
        (KJS::VarDeclNode::handleSlowCase):
        * kjs/nodes.h:
        (KJS::FunctionCallResolveNode::precedence):
        (KJS::AddNode::precedence):
        (KJS::AddNode::):
        (KJS::LessNumbersNode::):
        (KJS::LessStringsNode::):
        * kjs/value.cpp:
        (KJS::JSValue::toInt32SlowCase):
        (KJS::JSValue::toUInt32SlowCase):
        * kjs/value.h:
        (KJS::JSValue::asCell):
        (KJS::JSValue::toInt32):
        (KJS::JSValue::toUInt32):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@27747 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent f263e7d9
2007-11-12 Eric Seidel <eric@webkit.org>
Reviewed by Oliver.
Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
Fix a few missing evaluateToBoolean methods
Deploy all evaluateTo* functions to more nodes to avoid slowdowns
http://bugs.webkit.org/show_bug.cgi?id=15950
SunSpider claims this is at least a 1.4% speedup.
* kjs/JSImmediate.h:
(KJS::JSImmediate::getTruncatedInt32):
(KJS::JSImmediate::toDouble):
(KJS::JSImmediate::getUInt32):
* kjs/nodes.cpp:
(KJS::ExpressionNode::evaluateToNumber):
(KJS::ExpressionNode::evaluateToInt32):
(KJS::ExpressionNode::evaluateToUInt32):
(KJS::NumberNode::evaluateToInt32):
(KJS::NumberNode::evaluateToUInt32):
(KJS::ImmediateNumberNode::evaluateToInt32):
(KJS::ImmediateNumberNode::evaluateToUInt32):
(KJS::ResolveNode::evaluate):
(KJS::ResolveNode::evaluateToNumber):
(KJS::ResolveNode::evaluateToBoolean):
(KJS::ResolveNode::evaluateToInt32):
(KJS::ResolveNode::evaluateToUInt32):
(KJS::LocalVarAccessNode::evaluateToInt32):
(KJS::LocalVarAccessNode::evaluateToUInt32):
(KJS::BracketAccessorNode::evaluateToNumber):
(KJS::BracketAccessorNode::evaluateToBoolean):
(KJS::BracketAccessorNode::evaluateToInt32):
(KJS::BracketAccessorNode::evaluateToUInt32):
(KJS::DotAccessorNode::inlineEvaluate):
(KJS::DotAccessorNode::evaluate):
(KJS::DotAccessorNode::evaluateToNumber):
(KJS::DotAccessorNode::evaluateToBoolean):
(KJS::DotAccessorNode::evaluateToInt32):
(KJS::DotAccessorNode::evaluateToUInt32):
(KJS::NewExprNode::inlineEvaluate):
(KJS::NewExprNode::evaluate):
(KJS::NewExprNode::evaluateToNumber):
(KJS::NewExprNode::evaluateToBoolean):
(KJS::NewExprNode::evaluateToInt32):
(KJS::NewExprNode::evaluateToUInt32):
(KJS::FunctionCallResolveNode::inlineEvaluate):
(KJS::FunctionCallResolveNode::evaluate):
(KJS::FunctionCallResolveNode::evaluateToNumber):
(KJS::FunctionCallResolveNode::evaluateToBoolean):
(KJS::FunctionCallResolveNode::evaluateToInt32):
(KJS::FunctionCallResolveNode::evaluateToUInt32):
(KJS::LocalVarFunctionCallNode::evaluate):
(KJS::LocalVarFunctionCallNode::evaluateToNumber):
(KJS::LocalVarFunctionCallNode::evaluateToBoolean):
(KJS::LocalVarFunctionCallNode::evaluateToInt32):
(KJS::LocalVarFunctionCallNode::evaluateToUInt32):
(KJS::FunctionCallDotNode::evaluate):
(KJS::FunctionCallDotNode::evaluateToNumber):
(KJS::FunctionCallDotNode::evaluateToBoolean):
(KJS::FunctionCallDotNode::evaluateToInt32):
(KJS::FunctionCallDotNode::evaluateToUInt32):
(KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
(KJS::PostDecLocalVarNode::evaluateToNumber):
(KJS::PostDecLocalVarNode::evaluateToBoolean):
(KJS::PostDecLocalVarNode::evaluateToInt32):
(KJS::PostDecLocalVarNode::evaluateToUInt32):
(KJS::typeStringForValue):
(KJS::UnaryPlusNode::evaluate):
(KJS::UnaryPlusNode::evaluateToBoolean):
(KJS::UnaryPlusNode::evaluateToNumber):
(KJS::UnaryPlusNode::evaluateToInt32):
(KJS::BitwiseNotNode::inlineEvaluateToInt32):
(KJS::BitwiseNotNode::evaluate):
(KJS::BitwiseNotNode::evaluateToNumber):
(KJS::BitwiseNotNode::evaluateToBoolean):
(KJS::BitwiseNotNode::evaluateToInt32):
(KJS::MultNode::evaluateToBoolean):
(KJS::MultNode::evaluateToInt32):
(KJS::MultNode::evaluateToUInt32):
(KJS::DivNode::evaluateToInt32):
(KJS::DivNode::evaluateToUInt32):
(KJS::ModNode::evaluateToBoolean):
(KJS::ModNode::evaluateToInt32):
(KJS::ModNode::evaluateToUInt32):
(KJS::AddNode::evaluateToNumber):
(KJS::AddNode::evaluateToInt32):
(KJS::AddNode::evaluateToUInt32):
(KJS::AddNumbersNode::evaluateToInt32):
(KJS::AddNumbersNode::evaluateToUInt32):
(KJS::SubNode::evaluateToInt32):
(KJS::SubNode::evaluateToUInt32):
(KJS::LeftShiftNode::inlineEvaluateToInt32):
(KJS::LeftShiftNode::evaluate):
(KJS::LeftShiftNode::evaluateToNumber):
(KJS::LeftShiftNode::evaluateToInt32):
(KJS::RightShiftNode::inlineEvaluateToInt32):
(KJS::RightShiftNode::evaluate):
(KJS::RightShiftNode::evaluateToNumber):
(KJS::RightShiftNode::evaluateToInt32):
(KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
(KJS::UnsignedRightShiftNode::evaluate):
(KJS::UnsignedRightShiftNode::evaluateToNumber):
(KJS::UnsignedRightShiftNode::evaluateToInt32):
(KJS::LessNode::inlineEvaluateToBoolean):
(KJS::LessNode::evaluate):
(KJS::LessNode::evaluateToBoolean):
(KJS::LessNumbersNode::inlineEvaluateToBoolean):
(KJS::LessNumbersNode::evaluate):
(KJS::LessNumbersNode::evaluateToBoolean):
(KJS::LessStringsNode::inlineEvaluateToBoolean):
(KJS::LessStringsNode::evaluate):
(KJS::BitAndNode::evaluate):
(KJS::BitAndNode::inlineEvaluateToInt32):
(KJS::BitAndNode::evaluateToNumber):
(KJS::BitAndNode::evaluateToBoolean):
(KJS::BitAndNode::evaluateToInt32):
(KJS::BitXOrNode::inlineEvaluateToInt32):
(KJS::BitXOrNode::evaluate):
(KJS::BitXOrNode::evaluateToNumber):
(KJS::BitXOrNode::evaluateToBoolean):
(KJS::BitXOrNode::evaluateToInt32):
(KJS::BitOrNode::inlineEvaluateToInt32):
(KJS::BitOrNode::evaluate):
(KJS::BitOrNode::evaluateToNumber):
(KJS::BitOrNode::evaluateToBoolean):
(KJS::BitOrNode::evaluateToInt32):
(KJS::ConditionalNode::evaluateToNumber):
(KJS::ConditionalNode::evaluateToInt32):
(KJS::ConditionalNode::evaluateToUInt32):
(KJS::valueForReadModifyAssignment):
(KJS::AssignExprNode::evaluate):
(KJS::AssignExprNode::evaluateToBoolean):
(KJS::AssignExprNode::evaluateToNumber):
(KJS::AssignExprNode::evaluateToInt32):
(KJS::VarDeclNode::handleSlowCase):
* kjs/nodes.h:
(KJS::FunctionCallResolveNode::precedence):
(KJS::AddNode::precedence):
(KJS::AddNode::):
(KJS::LessNumbersNode::):
(KJS::LessStringsNode::):
* kjs/value.cpp:
(KJS::JSValue::toInt32SlowCase):
(KJS::JSValue::toUInt32SlowCase):
* kjs/value.h:
(KJS::JSValue::asCell):
(KJS::JSValue::toInt32):
(KJS::JSValue::toUInt32):
2007-11-12 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
......
......@@ -116,6 +116,8 @@ public:
static bool getTruncatedInt32(const JSValue*, int32_t&);
static bool getTruncatedUInt32(const JSValue*, uint32_t&);
static int32_t getTruncatedInt32(const JSValue*);
static JSValue* trueImmediate();
static JSValue* falseImmediate();
static JSValue* undefinedImmediate();
......@@ -238,10 +240,15 @@ ALWAYS_INLINE JSValue* JSImmediate::from(double d)
return tag(intVal << 2, NumberType);
}
ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(const JSValue* v)
{
return static_cast<int32_t>(unTag(v)) >> 2;
}
ALWAYS_INLINE double JSImmediate::toDouble(const JSValue* v)
{
ASSERT(isImmediate(v));
const int32_t i = static_cast<int32_t>(unTag(v)) >> 2;
const int32_t i = getTruncatedInt32(v);
if (JSImmediate::getTag(v) == UndefinedType && i)
return std::numeric_limits<double>::quiet_NaN();
return i;
......@@ -249,14 +256,14 @@ ALWAYS_INLINE double JSImmediate::toDouble(const JSValue* v)
ALWAYS_INLINE bool JSImmediate::getUInt32(const JSValue* v, uint32_t& i)
{
const int32_t si = static_cast<int32_t>(unTag(v)) >> 2;
const int32_t si = getTruncatedInt32(v);
i = si;
return isNumber(v) & (si >= 0);
}
ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(const JSValue* v, int32_t& i)
{
i = static_cast<int32_t>(unTag(v)) >> 2;
i = getTruncatedInt32(v);
return isNumber(v);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -72,11 +72,10 @@ double JSValue::toIntegerPreserveNaN(ExecState *exec) const
return trunc(toNumber(exec));
}
int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
int32_t JSValue::toInt32SlowCase(double d, bool& ok)
{
ok = true;
double d = toNumber(exec);
if (d >= -D32 / 2 && d < D32 / 2)
return static_cast<int32_t>(d);
......@@ -93,11 +92,15 @@ int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
return static_cast<int32_t>(d32);
}
uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
{
return JSValue::toInt32SlowCase(toNumber(exec), ok);
}
uint32_t JSValue::toUInt32SlowCase(double d, bool& ok)
{
ok = true;
double d = toNumber(exec);
if (d >= 0.0 && d < D32)
return static_cast<uint32_t>(d);
......@@ -112,6 +115,11 @@ uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
return static_cast<uint32_t>(d32);
}
uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
{
return JSValue::toUInt32SlowCase(toNumber(exec), ok);
}
float JSValue::toFloat(ExecState* exec) const
{
return static_cast<float>(toNumber(exec));
......
......@@ -97,6 +97,10 @@ public:
uint32_t toUInt32(ExecState*) const;
uint32_t toUInt32(ExecState*, bool& ok) const;
// These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)
static int32_t toInt32(double);
static int32_t toUInt32(double);
// Floating point conversions.
float toFloat(ExecState*) const;
......@@ -104,6 +108,9 @@ public:
void mark();
bool marked() const;
static int32_t toInt32SlowCase(double, bool& ok);
static uint32_t toUInt32SlowCase(double, bool& ok);
private:
int32_t toInt32SlowCase(ExecState*, bool& ok) const;
uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
......@@ -288,16 +295,16 @@ inline void JSCell::mark()
return Collector::markCell(this);
}
inline JSCell *JSValue::asCell()
ALWAYS_INLINE JSCell* JSValue::asCell()
{
ASSERT(!JSImmediate::isImmediate(this));
return static_cast<JSCell *>(this);
return static_cast<JSCell*>(this);
}
inline const JSCell *JSValue::asCell() const
ALWAYS_INLINE const JSCell* JSValue::asCell() const
{
ASSERT(!JSImmediate::isImmediate(this));
return static_cast<const JSCell *>(this);
return static_cast<const JSCell*>(this);
}
inline bool JSValue::isUndefined() const
......@@ -473,6 +480,24 @@ inline uint32_t JSValue::toUInt32(ExecState* exec) const
return toUInt32SlowCase(exec, ok);
}
inline int32_t JSValue::toInt32(double val)
{
if (!(val >= -2147483648.0 && val < 2147483648.0)) {
bool ignored;
return toInt32SlowCase(val, ignored);
}
return static_cast<int32_t>(val);
}
inline int32_t JSValue::toUInt32(double val)
{
if (!(val >= 0.0 && val < 4294967296.0)) {
bool ignored;
return toUInt32SlowCase(val, ignored);
}
return static_cast<uint32_t>(val);
}
inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
{
int32_t i;
......
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