Commit d2c36fec authored by mjs@apple.com's avatar mjs@apple.com

2008-10-06 Maciej Stachowiak <mjs@apple.com>

        Reviewed by Sam Weinig.
        
        - optimize op_jtrue, op_loop_if_true and op_not in various ways
        https://bugs.webkit.org/show_bug.cgi?id=21404
        
        1) Make JSValue::toBoolean nonvirtual and completely inline by
        making use of the StructureID type field.
        
        2) Make JSValue::toBoolean not take an ExecState; doesn't need it.
        
        3) Make op_not, op_loop_if_true and op_jtrue not read the
        ExecState (toBoolean doesn't need it any more) and not check
        exceptions (toBoolean can't throw).

        * API/JSValueRef.cpp:
        (JSValueToBoolean):
        * JavaScriptCore.exp:
        * VM/CodeBlock.cpp:
        (JSC::CodeBlock::dump):
        * VM/Machine.cpp:
        (JSC::Machine::privateExecute):
        (JSC::Machine::cti_op_loop_if_true):
        (JSC::Machine::cti_op_not):
        (JSC::Machine::cti_op_jtrue):
        * kjs/ArrayPrototype.cpp:
        (JSC::arrayProtoFuncFilter):
        (JSC::arrayProtoFuncEvery):
        (JSC::arrayProtoFuncSome):
        * kjs/BooleanConstructor.cpp:
        (JSC::constructBoolean):
        (JSC::callBooleanConstructor):
        * kjs/GetterSetter.h:
        * kjs/JSCell.h:
        (JSC::JSValue::toBoolean):
        * kjs/JSNumberCell.cpp:
        * kjs/JSNumberCell.h:
        (JSC::JSNumberCell::toBoolean):
        * kjs/JSObject.cpp:
        * kjs/JSObject.h:
        (JSC::JSObject::toBoolean):
        (JSC::JSCell::toBoolean):
        * kjs/JSString.cpp:
        * kjs/JSString.h:
        (JSC::JSString::toBoolean):
        * kjs/JSValue.h:
        * kjs/RegExpConstructor.cpp:
        (JSC::setRegExpConstructorMultiline):
        * kjs/RegExpObject.cpp:
        (JSC::RegExpObject::match):
        * kjs/RegExpPrototype.cpp:
        (JSC::regExpProtoFuncToString):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37333 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e4b1d4f6
......@@ -188,11 +188,9 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
return toRef(jsString(exec, string->ustring()));
}
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
bool JSValueToBoolean(JSContextRef, JSValueRef value)
{
ExecState* exec = toJS(ctx);
JSValue* jsValue = toJS(value);
return jsValue->toBoolean(exec);
return toJS(value)->toBoolean();
}
double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
......
2008-10-06 Maciej Stachowiak <mjs@apple.com>
Reviewed by Sam Weinig.
- optimize op_jtrue, op_loop_if_true and op_not in various ways
https://bugs.webkit.org/show_bug.cgi?id=21404
1) Make JSValue::toBoolean nonvirtual and completely inline by
making use of the StructureID type field.
2) Make JSValue::toBoolean not take an ExecState; doesn't need it.
3) Make op_not, op_loop_if_true and op_jtrue not read the
ExecState (toBoolean doesn't need it any more) and not check
exceptions (toBoolean can't throw).
* API/JSValueRef.cpp:
(JSValueToBoolean):
* JavaScriptCore.exp:
* VM/CodeBlock.cpp:
(JSC::CodeBlock::dump):
* VM/Machine.cpp:
(JSC::Machine::privateExecute):
(JSC::Machine::cti_op_loop_if_true):
(JSC::Machine::cti_op_not):
(JSC::Machine::cti_op_jtrue):
* kjs/ArrayPrototype.cpp:
(JSC::arrayProtoFuncFilter):
(JSC::arrayProtoFuncEvery):
(JSC::arrayProtoFuncSome):
* kjs/BooleanConstructor.cpp:
(JSC::constructBoolean):
(JSC::callBooleanConstructor):
* kjs/GetterSetter.h:
* kjs/JSCell.h:
(JSC::JSValue::toBoolean):
* kjs/JSNumberCell.cpp:
* kjs/JSNumberCell.h:
(JSC::JSNumberCell::toBoolean):
* kjs/JSObject.cpp:
* kjs/JSObject.h:
(JSC::JSObject::toBoolean):
(JSC::JSCell::toBoolean):
* kjs/JSString.cpp:
* kjs/JSString.h:
(JSC::JSString::toBoolean):
* kjs/JSValue.h:
* kjs/RegExpConstructor.cpp:
(JSC::setRegExpConstructorMultiline):
* kjs/RegExpObject.cpp:
(JSC::RegExpObject::match):
* kjs/RegExpPrototype.cpp:
(JSC::regExpProtoFuncToString):
2008-10-06 Ariya Hidayat <ariya.hidayat@trolltech.com>
Reviewed by Simon.
......
......@@ -335,7 +335,6 @@ __ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
__ZNK3JSC8JSObject9classNameEv
__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3JSC9CodeBlock17derefStructureIDsEPNS_11InstructionE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3WTF8Collator7collateEPKtmS2_m
......
......@@ -810,13 +810,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
break;
}
case op_tear_off_activation: {
int r0 = (++it)->u.operand;
printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
printf("[%4d] tear_off_activation\n", location);
break;
}
case op_tear_off_arguments: {
int r0 = (++it)->u.operand;
printf("[%4d] tear_off_arguments\t %s\n", location, registerName(r0).c_str());
printf("[%4d] tear_off_arguments\n", location);
break;
}
case op_ret: {
......
......@@ -2127,8 +2127,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
JSValue* result = jsBoolean(!r[src].jsValue(exec)->toBoolean(exec));
VM_CHECK_EXCEPTION();
JSValue* result = jsBoolean(!r[src].jsValue(exec)->toBoolean());
r[dst] = result;
++vPC;
......@@ -2986,7 +2985,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
if (r[cond].jsValue(exec)->toBoolean(exec)) {
if (r[cond].jsValue(exec)->toBoolean()) {
vPC += target;
CHECK_FOR_TIMEOUT();
NEXT_OPCODE;
......@@ -3003,7 +3002,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
if (r[cond].jsValue(exec)->toBoolean(exec)) {
if (r[cond].jsValue(exec)->toBoolean()) {
vPC += target;
NEXT_OPCODE;
}
......@@ -3019,7 +3018,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile,
*/
int cond = (++vPC)->u.operand;
int target = (++vPC)->u.operand;
if (!r[cond].jsValue(exec)->toBoolean(exec)) {
if (!r[cond].jsValue(exec)->toBoolean()) {
vPC += target;
NEXT_OPCODE;
}
......@@ -4988,11 +4987,7 @@ int Machine::cti_op_loop_if_true(CTI_ARGS)
{
JSValue* src1 = ARG_src1;
ExecState* exec = ARG_exec;
bool result = src1->toBoolean(exec);
VM_CHECK_EXCEPTION_AT_END();
return result;
return src1->toBoolean();
}
JSValue* Machine::cti_op_negate(CTI_ARGS)
......@@ -5115,24 +5110,12 @@ int Machine::cti_op_jless(CTI_ARGS)
JSValue* Machine::cti_op_not(CTI_ARGS)
{
JSValue* src = ARG_src1;
ExecState* exec = ARG_exec;
JSValue* result = jsBoolean(!src->toBoolean(exec));
VM_CHECK_EXCEPTION_AT_END();
return result;
return jsBoolean(!ARG_src1->toBoolean());
}
int SFX_CALL Machine::cti_op_jtrue(CTI_ARGS)
{
JSValue* src1 = ARG_src1;
ExecState* exec = ARG_exec;
bool result = src1->toBoolean(exec);
VM_CHECK_EXCEPTION_AT_END();
return result;
return ARG_src1->toBoolean();
}
JSValue* Machine::cti_op_post_inc(CTI_ARGS)
......
......@@ -582,7 +582,7 @@ JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue* thisValue, co
JSValue* result = call(exec, function, callType, callData, applyThis, eachArguments);
if (result->toBoolean(exec))
if (result->toBoolean())
resultArray->put(exec, filterIndex++, v);
}
return resultArray;
......@@ -656,7 +656,7 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue* thisValue, con
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean();
if (!predicateResult) {
result = jsBoolean(false);
......@@ -720,7 +720,7 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue* thisValue, cons
eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean(exec);
bool predicateResult = call(exec, function, callType, callData, applyThis, eachArguments)->toBoolean();
if (predicateResult) {
result = jsBoolean(true);
......
......@@ -41,7 +41,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<StructureID>
JSObject* constructBoolean(ExecState* exec, const ArgList& args)
{
BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
obj->setInternalValue(jsBoolean(args.at(exec, 0)->toBoolean(exec)));
obj->setInternalValue(jsBoolean(args.at(exec, 0)->toBoolean()));
return obj;
}
......@@ -59,7 +59,7 @@ ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
// ECMA 15.6.1
static JSValue* callBooleanConstructor(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
{
return jsBoolean(args.at(exec, 0)->toBoolean(exec));
return jsBoolean(args.at(exec, 0)->toBoolean());
}
CallType BooleanConstructor::getCallData(CallData& callData)
......
......@@ -52,7 +52,7 @@ namespace JSC {
virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState*) const;
bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
......
......@@ -72,7 +72,7 @@ namespace JSC {
// Basic conversions.
virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0;
virtual bool toBoolean(ExecState*) const = 0;
bool toBoolean() const;
virtual double toNumber(ExecState*) const = 0;
virtual UString toString(ExecState*) const = 0;
virtual JSObject* toObject(ExecState*) const = 0;
......@@ -272,9 +272,9 @@ namespace JSC {
return asCell()->getPrimitiveNumber(exec, number, value);
}
inline bool JSValue::toBoolean(ExecState* exec) const
inline bool JSValue::toBoolean() const
{
return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean(exec);
return JSImmediate::isImmediate(this) ? JSImmediate::toBoolean(this) : asCell()->toBoolean();
}
ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
......
......@@ -40,11 +40,6 @@ bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue*& valu
return true;
}
bool JSNumberCell::toBoolean(ExecState*) const
{
return m_value < 0.0 || m_value > 0.0; // false for NaN
}
double JSNumberCell::toNumber(ExecState*) const
{
return m_value;
......
......@@ -52,7 +52,7 @@ namespace JSC {
virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState*) const;
bool toBoolean() const { return m_value < 0.0 || m_value > 0.0; /* false for NaN */ }
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
......
......@@ -430,11 +430,6 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName
m_structureID->getEnumerablePropertyNames(exec, propertyNames, this);
}
bool JSObject::toBoolean(ExecState*) const
{
return true;
}
double JSObject::toNumber(ExecState* exec) const
{
JSValue* primitive = toPrimitive(exec, PreferNumber);
......
......@@ -28,6 +28,7 @@
#include "CommonIdentifiers.h"
#include "ExecState.h"
#include "JSNumberCell.h"
#include "JSString.h"
#include "PropertyMap.h"
#include "PropertySlot.h"
#include "PutPropertySlot.h"
......@@ -109,7 +110,7 @@ namespace JSC {
virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState*) const;
bool toBoolean() const { return true; }
virtual double toNumber(ExecState*) const;
virtual UString toString(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
......@@ -246,6 +247,17 @@ inline bool JSCell::isObject(const ClassInfo* info) const
return false;
}
inline bool JSCell::toBoolean() const
{
JSType type = structureID()->typeInfo().type();
if (type == NumberType)
return static_cast<const JSNumberCell*>(this)->toBoolean();
if (type == ObjectType)
return static_cast<const JSObject*>(this)->toBoolean();
ASSERT(type == StringType);
return static_cast<const JSString*>(this)->toBoolean();
}
// this method is here to be after the inline declaration of JSCell::isObject
inline bool JSValue::isObject(const ClassInfo* classInfo) const
{
......
......@@ -42,11 +42,6 @@ bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue*& value)
return false;
}
bool JSString::toBoolean(ExecState*) const
{
return !m_value.isEmpty();
}
double JSString::toNumber(ExecState*) const
{
return m_value.toDouble();
......
......@@ -92,6 +92,8 @@ namespace JSC {
static PassRefPtr<StructureID> createStructureID(JSValue* proto) { return StructureID::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
bool toBoolean() const { return !m_value.isEmpty(); }
private:
enum VPtrStealingHackType { VPtrStealingHack };
JSString(VPtrStealingHackType)
......@@ -101,7 +103,6 @@ namespace JSC {
virtual JSValue* toPrimitive(ExecState*, PreferredPrimitiveType) const;
virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
virtual bool toBoolean(ExecState*) const;
virtual double toNumber(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
virtual UString toString(ExecState*) const;
......
......@@ -96,7 +96,7 @@ namespace JSC {
JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
bool toBoolean(ExecState*) const;
bool toBoolean() const;
// toNumber conversion is expected to be side effect free if an exception has
// been set in the ExecState already.
......
......@@ -311,9 +311,9 @@ void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue* v
static_cast<RegExpConstructor*>(baseObject)->setInput(value->toString(exec));
}
void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue* value)
void setRegExpConstructorMultiline(ExecState*, JSObject* baseObject, JSValue* value)
{
static_cast<RegExpConstructor*>(baseObject)->setMultiline(value->toBoolean(exec));
static_cast<RegExpConstructor*>(baseObject)->setMultiline(value->toBoolean());
}
// ECMA 15.10.4
......
......@@ -121,7 +121,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
}
}
bool global = get(exec, exec->propertyNames().global)->toBoolean(exec);
bool global = get(exec, exec->propertyNames().global)->toBoolean();
int lastIndex = 0;
if (global) {
if (d->lastIndex < 0 || d->lastIndex > input.size()) {
......
......@@ -106,11 +106,11 @@ JSValue* regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue* thisValue,
UString result = "/" + static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().source)->toString(exec);
result.append('/');
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().global)->toBoolean(exec))
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().global)->toBoolean())
result.append('g');
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean(exec))
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().ignoreCase)->toBoolean())
result.append('i');
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
if (static_cast<RegExpObject*>(thisValue)->get(exec, exec->propertyNames().multiline)->toBoolean())
result.append('m');
return jsNontrivialString(exec, result);
}
......
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