aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-04-13 20:58:21 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-04-14 07:10:09 +0200
commit3dbd772cc4c3e0cff133d401c6986b013d507eb9 (patch)
tree5297ccbaa14f584e9293190ece1f87e754c0d7e3 /src
parent802fe16471828bb52c4e8106d09e6191bd975db3 (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.cpp1
-rw-r--r--src/v4/qv4lookup.cpp78
-rw-r--r--src/v4/qv4lookup.h6
-rw-r--r--src/v4/qv4runtime.cpp2
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)