Some smaller optimizations for indexed property access
Saves around 1% of instructions on crypto.js Change-Id: Iccef08b204e6e752d827242baf156efd9a4d58a7 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
d3bff5843b
commit
8c322d89ee
|
@ -118,7 +118,8 @@ ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs
|
||||||
|
|
||||||
ReturnedValue Lookup::indexedGetterGeneric(Lookup *l, const Value &object, const Value &index)
|
ReturnedValue Lookup::indexedGetterGeneric(Lookup *l, const Value &object, const Value &index)
|
||||||
{
|
{
|
||||||
if (object.isObject() && index.asArrayIndex() < UINT_MAX) {
|
uint idx;
|
||||||
|
if (object.isObject() && index.asArrayIndex(idx)) {
|
||||||
l->indexedGetter = indexedGetterObjectInt;
|
l->indexedGetter = indexedGetterObjectInt;
|
||||||
return indexedGetterObjectInt(l, object, index);
|
return indexedGetterObjectInt(l, object, index);
|
||||||
}
|
}
|
||||||
|
@ -129,11 +130,12 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
|
||||||
{
|
{
|
||||||
Q_UNUSED(l);
|
Q_UNUSED(l);
|
||||||
Scope scope(l->engine);
|
Scope scope(l->engine);
|
||||||
uint idx = index.asArrayIndex();
|
uint idx;
|
||||||
|
bool isInt = index.asArrayIndex(idx);
|
||||||
|
|
||||||
ScopedObject o(scope, object);
|
ScopedObject o(scope, object);
|
||||||
if (!o) {
|
if (!o) {
|
||||||
if (idx < UINT_MAX) {
|
if (isInt) {
|
||||||
if (const String *str = object.as<String>()) {
|
if (const String *str = object.as<String>()) {
|
||||||
if (idx >= (uint)str->toQString().length()) {
|
if (idx >= (uint)str->toQString().length()) {
|
||||||
return Encode::undefined();
|
return Encode::undefined();
|
||||||
|
@ -153,7 +155,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
|
||||||
return Encode::undefined();
|
return Encode::undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx < UINT_MAX) {
|
if (isInt) {
|
||||||
if (o->d()->arrayData && !o->d()->arrayData->attrs) {
|
if (o->d()->arrayData && !o->d()->arrayData->attrs) {
|
||||||
ScopedValue v(scope, Scoped<ArrayData>(scope, o->arrayData())->get(idx));
|
ScopedValue v(scope, Scoped<ArrayData>(scope, o->arrayData())->get(idx));
|
||||||
if (!v->isEmpty())
|
if (!v->isEmpty())
|
||||||
|
@ -173,14 +175,17 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, cons
|
||||||
|
|
||||||
ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index)
|
ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index)
|
||||||
{
|
{
|
||||||
uint idx = index.asArrayIndex();
|
uint idx;
|
||||||
if (idx != UINT_MAX) {
|
if (index.asArrayIndex(idx)) {
|
||||||
if (Object *o = object.objectValue()) {
|
if (Heap::Base *b = object.heapObject()) {
|
||||||
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
|
if (b->vtable()->isObject) {
|
||||||
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
|
Heap::Object *o = static_cast<Heap::Object *>(b);
|
||||||
if (idx < s->len)
|
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
|
||||||
if (!s->data(idx).isEmpty())
|
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
|
||||||
return s->data(idx).asReturnedValue();
|
if (idx < s->len)
|
||||||
|
if (!s->data(idx).isEmpty())
|
||||||
|
return s->data(idx).asReturnedValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +196,8 @@ ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, con
|
||||||
void Lookup::indexedSetterGeneric(Lookup *l, const Value &object, const Value &index, const Value &v)
|
void Lookup::indexedSetterGeneric(Lookup *l, const Value &object, const Value &index, const Value &v)
|
||||||
{
|
{
|
||||||
if (Object *o = object.objectValue()) {
|
if (Object *o = object.objectValue()) {
|
||||||
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple && index.asArrayIndex() < UINT_MAX) {
|
uint idx;
|
||||||
|
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple && index.asArrayIndex(idx)) {
|
||||||
l->indexedSetter = indexedSetterObjectInt;
|
l->indexedSetter = indexedSetterObjectInt;
|
||||||
indexedSetterObjectInt(l, object, index, v);
|
indexedSetterObjectInt(l, object, index, v);
|
||||||
return;
|
return;
|
||||||
|
@ -207,8 +213,8 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &
|
||||||
if (scope.engine->hasException)
|
if (scope.engine->hasException)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint idx = index.asArrayIndex();
|
uint idx;
|
||||||
if (idx < UINT_MAX) {
|
if (index.asArrayIndex(idx)) {
|
||||||
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
|
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
|
||||||
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
|
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
|
||||||
if (idx < s->len) {
|
if (idx < s->len) {
|
||||||
|
@ -226,14 +232,17 @@ void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &
|
||||||
|
|
||||||
void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v)
|
void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v)
|
||||||
{
|
{
|
||||||
uint idx = index.asArrayIndex();
|
uint idx;
|
||||||
if (idx != UINT_MAX) {
|
if (index.asArrayIndex(idx)) {
|
||||||
if (Object *o = object.objectValue()) {
|
if (Heap::Base *b = object.heapObject()) {
|
||||||
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
|
if (b->vtable()->isObject) {
|
||||||
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
|
Heap::Object *o = static_cast<Heap::Object *>(b);
|
||||||
if (idx < s->len) {
|
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
|
||||||
s->data(idx) = v;
|
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
|
||||||
return;
|
if (idx < s->len) {
|
||||||
|
s->data(idx) = v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,6 +453,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint asArrayIndex() const;
|
inline uint asArrayIndex() const;
|
||||||
|
inline bool asArrayIndex(uint &idx) const;
|
||||||
#ifndef V4_BOOTSTRAP
|
#ifndef V4_BOOTSTRAP
|
||||||
uint asArrayLength(bool *ok) const;
|
uint asArrayLength(bool *ok) const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -531,6 +532,20 @@ inline uint Value::asArrayIndex() const
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Value::asArrayIndex(uint &idx) const
|
||||||
|
{
|
||||||
|
if (!isDouble()) {
|
||||||
|
if (isInteger() && int_32() >= 0) {
|
||||||
|
idx = (uint)int_32();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
double d = doubleValue();
|
||||||
|
idx = (uint)d;
|
||||||
|
return (idx == d);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|
Loading…
Reference in New Issue