diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-04-13 20:58:21 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2013-04-14 07:10:09 +0200 |
commit | 3dbd772cc4c3e0cff133d401c6986b013d507eb9 (patch) | |
tree | 5297ccbaa14f584e9293190ece1f87e754c0d7e3 /src | |
parent | 802fe16471828bb52c4e8106d09e6191bd975db3 (diff) |
Introduce specialized lookup methods
Add specialized lookup methods for data properties.
Speeds up the v8 benchmark by ~10%
Change-Id: Ib61a59529b6eaba1ac5ad3020fd1ff52594b7ddf
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/v4/qv4isel_masm.cpp | 1 | ||||
-rw-r--r-- | src/v4/qv4lookup.cpp | 78 | ||||
-rw-r--r-- | src/v4/qv4lookup.h | 6 | ||||
-rw-r--r-- | src/v4/qv4runtime.cpp | 2 |
4 files changed, 77 insertions, 10 deletions
diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 9205eac41a..9d8795f198 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -1187,6 +1187,7 @@ uint InstructionSelection::addLookup(VM::String *name) { uint index = (uint)_lookups.size(); VM::Lookup l; + l.lookupProperty = Lookup::lookupPropertyGeneric; for (int i = 0; i < Lookup::Size; ++i) l.classList[i] = 0; l.level = -1; diff --git a/src/v4/qv4lookup.cpp b/src/v4/qv4lookup.cpp index 5e00a82522..991ab2b617 100644 --- a/src/v4/qv4lookup.cpp +++ b/src/v4/qv4lookup.cpp @@ -45,26 +45,88 @@ QT_BEGIN_NAMESPACE namespace QQmlJS { namespace VM { -void QQmlJS::VM::Lookup::lookupName(QQmlJS::VM::Lookup *l, ExecutionContext *ctx, QQmlJS::VM::Value *result, const QQmlJS::VM::Value &object) +void Lookup::lookupPropertyGeneric(QQmlJS::VM::Lookup *l, ExecutionContext *ctx, QQmlJS::VM::Value *result, const QQmlJS::VM::Value &object) { - Value res; if (Object *o = object.asObject()) { PropertyAttributes attrs; Property *p = l->lookup(o, &attrs); - if (p) - res = attrs.isData() ? p->value : o->getValue(ctx, p, attrs); - else - res = Value::undefinedValue(); + if (p) { + if (attrs.isData()) { + if (l->level == 0) + l->lookupProperty = lookupProperty0; + else if (l->level == 1) + l->lookupProperty = lookupProperty1; + else if (l->level == 2) + l->lookupProperty = lookupProperty2; + if (result) + *result = p->value; + return; + } else { + Value res = o->getValue(ctx, p, attrs); + if (result) + *result = res; + return; + } + } else if (result) { + *result = Value::undefinedValue(); + } } else { + Value res; if (Managed *m = object.asManaged()) { res = m->get(ctx, l->name); } else { o = __qmljs_convert_to_object(ctx, object); res = o->get(ctx, l->name); } + if (result) + *result = res; + } +} + +void Lookup::lookupProperty0(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object) +{ + if (Object *o = object.asObject()) { + if (l->classList[0] == o->internalClass) { + if (result) + *result = o->memberData[l->index].value; + return; + } + } + l->lookupProperty = lookupPropertyGeneric; + lookupPropertyGeneric(l, ctx, result, object); +} + +void Lookup::lookupProperty1(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object) +{ + if (Object *o = object.asObject()) { + if (l->classList[0] == o->internalClass && + l->classList[1] == o->prototype->internalClass) { + if (result) + *result = o->prototype->memberData[l->index].value; + return; + } + } + l->lookupProperty = lookupPropertyGeneric; + lookupPropertyGeneric(l, ctx, result, object); +} + +void Lookup::lookupProperty2(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object) +{ + if (Object *o = object.asObject()) { + if (l->classList[0] == o->internalClass) { + o = o->prototype; + if (l->classList[1] == o->internalClass) { + o = o->prototype; + if (l->classList[2] == o->internalClass) { + if (result) + *result = o->prototype->memberData[l->index].value; + return; + } + } + } } - if (result) - *result = res; + l->lookupProperty = lookupPropertyGeneric; + lookupPropertyGeneric(l, ctx, result, object); } } diff --git a/src/v4/qv4lookup.h b/src/v4/qv4lookup.h index d670d8e550..c51940ac2d 100644 --- a/src/v4/qv4lookup.h +++ b/src/v4/qv4lookup.h @@ -55,12 +55,16 @@ namespace VM { struct Lookup { enum { Size = 4 }; + void (*lookupProperty)(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); InternalClass *classList[Size]; int level; uint index; String *name; - static void lookupName(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); + static void lookupPropertyGeneric(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); + static void lookupProperty0(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); + static void lookupProperty1(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); + static void lookupProperty2(Lookup *l, ExecutionContext *ctx, Value *result, const Value &object); Property *lookup(Object *obj, PropertyAttributes *attrs) { int i = 0; diff --git a/src/v4/qv4runtime.cpp b/src/v4/qv4runtime.cpp index edec0a293e..b6a7dd6c99 100644 --- a/src/v4/qv4runtime.cpp +++ b/src/v4/qv4runtime.cpp @@ -725,7 +725,7 @@ void __qmljs_get_property_lookup(ExecutionContext *ctx, Value *result, const Val { Value res; Lookup *l = ctx->lookups + lookupIndex; - l->lookupName(l, ctx, result, object); + l->lookupProperty(l, ctx, result, object); } void __qmljs_set_property_lookup(ExecutionContext *ctx, const Value &object, int lookupIndex, const Value &value) |