Commit 64fa293b authored by ggaren@apple.com's avatar ggaren@apple.com

2007-08-16 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Oliver Hunt.
        
        Sped up property access for array.length and string.length by adding a
        mechanism for returning a temporary value directly instead of returning
        a pointer to a function that retrieves the value.
        
        Also removed some unused cruft from PropertySlot.
        
        SunSpider says 0.5% - 1.2% faster.

        NOTE: This optimization is not a good idea in general, because it's
        actually a pessimization in the case of resolve for assignment,
        and it may get in the way of other optimizations in the future.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@35806 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d057577a
2008-08-16 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Sped up property access for array.length and string.length by adding a
mechanism for returning a temporary value directly instead of returning
a pointer to a function that retrieves the value.
Also removed some unused cruft from PropertySlot.
SunSpider says 0.5% - 1.2% faster.
NOTE: This optimization is not a good idea in general, because it's
actually a pessimization in the case of resolve for assignment,
and it may get in the way of other optimizations in the future.
2008-08-16 Dan Bernstein <mitz@apple.com>
Reviewed by Geoffrey Garen.
......
......@@ -103,7 +103,6 @@ __ZN3KJS11PropertyMapD1Ev
__ZN3KJS12DateInstance4infoE
__ZN3KJS12JSGlobalData6createEv
__ZN3KJS12JSGlobalDataD1Ev
__ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
__ZN3KJS12SamplingTool4dumpEPNS_9ExecStateE
__ZN3KJS12SamplingTool4stopEv
__ZN3KJS12SamplingTool5startEj
......
......@@ -1625,9 +1625,6 @@
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
projectRoots = (
"",
);
targets = (
932F5BE30822A1C700736975 /* All */,
932F5B3E0822A1C700736975 /* JavaScriptCore */,
......
......@@ -173,11 +173,6 @@ JSArray::~JSArray()
fastFree(m_storage);
}
JSValue* JSArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsNumber(exec, static_cast<JSArray*>(slot.slotBase())->m_length);
}
bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
{
ArrayStorage* storage = m_storage;
......@@ -210,7 +205,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().length) {
slot.setCustom(this, lengthGetter);
slot.setValue(jsNumber(exec, getLength()));
return true;
}
......
......@@ -81,8 +81,6 @@ namespace KJS {
private:
virtual const ClassInfo* classInfo() const { return &info; }
static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
void putSlowCase(ExecState*, unsigned propertyName, JSValue*);
......
......@@ -82,21 +82,6 @@ JSObject* JSString::toThisObject(ExecState* exec) const
return StringObject::create(exec, const_cast<JSString*>(this));
}
JSValue* JSString::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsNumber(exec, static_cast<JSString*>(slot.slotBase())->value().size());
}
JSValue* JSString::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
}
JSValue* JSString::indexNumericPropertyGetter(ExecState* exec, unsigned index, const PropertySlot& slot)
{
return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
}
bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
// The semantics here are really getPropertySlot, not getOwnPropertySlot.
......@@ -119,7 +104,7 @@ bool JSString::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Proper
{
// The semantics here are really getPropertySlot, not getOwnPropertySlot.
// This function should only be called by JSValue::get.
if (getStringPropertySlot(propertyName, slot))
if (getStringPropertySlot(exec, propertyName, slot))
return true;
return JSString::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}
......
......@@ -27,6 +27,7 @@
#include "CommonIdentifiers.h"
#include "ExecState.h"
#include "JSCell.h"
#include "JSNumberCell.h"
#include "PropertySlot.h"
#include "identifier.h"
#include "ustring.h"
......@@ -50,7 +51,7 @@ namespace KJS {
const UString& value() const { return m_value; }
bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
bool getStringPropertySlot(unsigned propertyName, PropertySlot&);
bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
JSValue* getIndex(ExecState* exec, unsigned i)
......@@ -77,10 +78,6 @@ namespace KJS {
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
static JSValue* lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* indexGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* indexNumericPropertyGetter(ExecState*, unsigned, const PropertySlot&);
UString m_value;
};
......@@ -95,24 +92,24 @@ namespace KJS {
ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (propertyName == exec->propertyNames().length) {
slot.setCustom(this, lengthGetter);
slot.setValue(jsNumber(exec, value().size()));
return true;
}
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
if (isStrictUInt32 && i < static_cast<unsigned>(m_value.size())) {
slot.setCustomIndex(this, i, indexGetter);
slot.setValue(jsString(exec, value().substr(i, 1)));
return true;
}
return false;
}
ALWAYS_INLINE bool JSString::getStringPropertySlot(unsigned propertyName, PropertySlot& slot)
ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
if (propertyName < static_cast<unsigned>(m_value.size())) {
slot.setCustomNumeric(this, indexNumericPropertyGetter);
slot.setValue(jsString(exec, value().substr(propertyName, 1)));
return true;
}
......
......@@ -27,11 +27,6 @@
namespace KJS {
JSValue* PropertySlot::undefinedGetter(ExecState*, const Identifier&, const PropertySlot&)
{
return jsUndefined();
}
JSValue* PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
// Prevent getter functions from observing execution if an exception is pending.
......
......@@ -34,22 +34,22 @@ namespace KJS {
#define KJS_VALUE_SLOT_MARKER 0
#define KJS_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
#define KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER reinterpret_cast<GetValueFunc>(2)
class PropertySlot {
public:
PropertySlot()
{
clearBase();
clearValue();
}
explicit PropertySlot(JSValue* base)
: m_slotBase(base)
{
clearValue();
}
typedef JSValue* (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
typedef JSValue* (*GetValueNumericFunc)(ExecState*, unsigned index, const PropertySlot&);
JSValue* getValue(ExecState* exec, const Identifier& propertyName) const
{
......@@ -57,7 +57,6 @@ namespace KJS {
return *m_data.valueSlot;
if (m_getValue == KJS_REGISTER_SLOT_MARKER)
return (*m_data.registerSlot).jsValue(exec);
ASSERT(m_getValue != KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER);
return m_getValue(exec, propertyName, *this);
}
......@@ -65,8 +64,6 @@ namespace KJS {
{
if (m_getValue == KJS_VALUE_SLOT_MARKER)
return *m_data.valueSlot;
if (m_getValue == KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER)
return m_data.numericFunc(exec, propertyName, *this);
if (m_getValue == KJS_REGISTER_SLOT_MARKER)
return (*m_data.registerSlot).jsValue(exec);
return m_getValue(exec, Identifier::from(exec, propertyName), *this);
......@@ -90,6 +87,15 @@ namespace KJS {
m_data.valueSlot = valueSlot;
}
void setValue(JSValue* value)
{
ASSERT(value);
m_getValue = KJS_VALUE_SLOT_MARKER;
clearBase();
m_value = value;
m_data.valueSlot = &m_value;
}
void setRegisterSlot(Register* registerSlot)
{
ASSERT(registerSlot);
......@@ -125,15 +131,6 @@ namespace KJS {
m_data.index = index;
}
void setCustomNumeric(JSValue* slotBase, GetValueNumericFunc getValue)
{
ASSERT(slotBase);
ASSERT(getValue);
m_slotBase = slotBase;
m_getValue = KJS_NUMERIC_PROPERTY_NAME_SLOT_MARKER;
m_data.numericFunc = getValue;
}
void setGetterSlot(JSObject* getterFunc)
{
ASSERT(getterFunc);
......@@ -144,7 +141,7 @@ namespace KJS {
void setUndefined()
{
clearBase();
m_getValue = undefinedGetter;
setValue(jsUndefined());
}
JSValue* slotBase() const
......@@ -167,14 +164,22 @@ namespace KJS {
#endif
}
void clearValue()
{
#ifndef NDEBUG
m_value = 0;
#endif
}
const HashEntry* staticEntry() const { return m_data.staticEntry; }
unsigned index() const { return m_data.index; }
private:
static JSValue* undefinedGetter(ExecState*, const Identifier&, const PropertySlot&);
static JSValue* functionGetter(ExecState*, const Identifier&, const PropertySlot&);
GetValueFunc m_getValue;
JSValue* m_value;
JSValue* m_slotBase;
union {
......@@ -183,7 +188,6 @@ namespace KJS {
Register* registerSlot;
const HashEntry* staticEntry;
unsigned index;
GetValueNumericFunc numericFunc;
} m_data;
};
......
......@@ -54,7 +54,7 @@ bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
if (internalValue()->getStringPropertySlot(propertyName, slot))
if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
return true;
return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
}
......
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