Change activition property calls to be pointer based
authorLars Knoll <lars.knoll@digia.com>
Wed, 13 Feb 2013 13:15:08 +0000 (14:15 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Wed, 13 Feb 2013 21:49:15 +0000 (22:49 +0100)
After longer discussions, we actually found out that
passing Values by reference (ie. as pointers) is most
likely quite a bit more efficient then passing them by
value. This is esp. true on 32bit platforms.

So change the runtime back to a pointer based calling
convention.

Change-Id: I948d361b6876109d77fc58f11ceb47109cf631d1
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
13 files changed:
src/v4/llvm_runtime.cpp
src/v4/moth/qv4isel_moth.cpp
src/v4/moth/qv4isel_moth_p.h
src/v4/moth/qv4vme_moth.cpp
src/v4/qmljs_runtime.cpp
src/v4/qmljs_runtime.h
src/v4/qv4codegen.cpp
src/v4/qv4isel_llvm.cpp
src/v4/qv4isel_llvm_p.h
src/v4/qv4isel_masm.cpp
src/v4/qv4isel_masm_p.h
src/v4/qv4isel_p.cpp
src/v4/qv4isel_p.h

index 212c8d1..828fee3 100644 (file)
@@ -400,7 +400,7 @@ String *__qmljs_llvm_identifier_from_utf8(ExecutionContext *ctx, const char *str
 
 void __qmljs_llvm_call_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
 {
-    *result = __qmljs_call_activation_property(context, name, args, argc);
+    __qmljs_call_activation_property(context, result, name, args, argc);
 }
 
 void __qmljs_llvm_call_value(ExecutionContext *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc)
@@ -411,7 +411,7 @@ void __qmljs_llvm_call_value(ExecutionContext *context, Value *result, const Val
 
 void __qmljs_llvm_construct_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
 {
-    *result = __qmljs_construct_activation_property(context, name, args, argc);
+    __qmljs_construct_activation_property(context, result, name, args, argc);
 }
 
 void __qmljs_llvm_construct_value(ExecutionContext *context, Value *result, const Value *func, Value *args, int argc)
@@ -421,12 +421,12 @@ void __qmljs_llvm_construct_value(ExecutionContext *context, Value *result, cons
 
 void __qmljs_llvm_get_activation_property(ExecutionContext *ctx, Value *result, String *name)
 {
-    *result = __qmljs_get_activation_property(ctx, name);
+    __qmljs_get_activation_property(ctx, result, name);
 }
 
 void __qmljs_llvm_set_activation_property(ExecutionContext *ctx, String *name, Value *value)
 {
-    __qmljs_set_activation_property(ctx, name, *value);
+    __qmljs_set_activation_property(ctx, name, value);
 }
 
 void __qmljs_llvm_get_property(ExecutionContext *ctx, Value *result, Value *object, String *name)
index 87b21aa..e9ec409 100644 (file)
@@ -419,7 +419,7 @@ void InstructionSelection::getActivationProperty(const QString &name, IR::Temp *
     addInstruction(load);
 }
 
-void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
+void InstructionSelection::setActivationProperty(IR::Temp *source, const QString &targetName)
 {
     Instruction::StoreName store;
     store.source = getParam(source);
index 012a26b..6dfc1e8 100644 (file)
@@ -66,7 +66,7 @@ protected:
     virtual void loadString(const QString &str, IR::Temp *targetTemp);
     virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *targetTemp);
     virtual void getActivationProperty(const QString &name, IR::Temp *temp);
-    virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
+    virtual void setActivationProperty(IR::Temp *source, const QString &targetName);
     virtual void initClosure(IR::Closure *closure, IR::Temp *target);
     virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target);
     virtual void setProperty(IR::Expr *source, IR::Temp *targetBase, const QString &targetName);
index fc06e90..d526bf1 100644 (file)
@@ -177,12 +177,12 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
 
     MOTH_BEGIN_INSTR(LoadName)
         TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
-        VALUE(instr.result) = __qmljs_get_activation_property(context, instr.name);
+        __qmljs_get_activation_property(context, VALUEPTR(instr.result), instr.name);
     MOTH_END_INSTR(LoadName)
 
     MOTH_BEGIN_INSTR(StoreName)
         TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
-        __qmljs_set_activation_property(context, instr.name, VALUE(instr.source));
+        __qmljs_set_activation_property(context, instr.name, VALUEPTR(instr.source));
     MOTH_END_INSTR(StoreName)
 
     MOTH_BEGIN_INSTR(LoadElement)
@@ -240,7 +240,7 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
     MOTH_BEGIN_INSTR(CallActivationProperty)
         Q_ASSERT(instr.args + instr.argc < stackSize);
         VM::Value *args = stack + instr.args;
-        VALUE(instr.result) = __qmljs_call_activation_property(context, instr.name, args, instr.argc);
+        __qmljs_call_activation_property(context, VALUEPTR(instr.result), instr.name, args, instr.argc);
     MOTH_END_INSTR(CallActivationProperty)
 
     MOTH_BEGIN_INSTR(CallBuiltinThrow)
@@ -391,7 +391,7 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
         TRACE(inline, "property name = %s, args = %d, argc = %d", instr.name->toQString().toUtf8().constData(), instr.args, instr.argc);
         Q_ASSERT(instr.args + instr.argc < stackSize);
         VM::Value *args = stack + instr.args;
-        VALUE(instr.result) = __qmljs_construct_activation_property(context, instr.name, args, instr.argc);
+        __qmljs_construct_activation_property(context, VALUEPTR(instr.result), instr.name, args, instr.argc);
     MOTH_END_INSTR(CreateActivationProperty)
 
     MOTH_BEGIN_INSTR(Jump)
index 4c77715..fcaa6a8 100644 (file)
@@ -648,9 +648,9 @@ Value __qmljs_foreach_next_property_name(Value foreach_iterator)
 }
 
 
-void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, Value value)
+void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, const Value *value)
 {
-    ctx->setProperty(name, value);
+    ctx->setProperty(name, *value);
 }
 
 Value __qmljs_get_property(ExecutionContext *ctx, Value object, String *name)
@@ -671,9 +671,9 @@ Value __qmljs_get_property(ExecutionContext *ctx, Value object, String *name)
     }
 }
 
-Value __qmljs_get_activation_property(ExecutionContext *ctx, String *name)
+void __qmljs_get_activation_property(ExecutionContext *ctx, Value *result, String *name)
 {
-    return ctx->getProperty(name);
+    *result = ctx->getProperty(name);
 }
 
 Value __qmljs_get_property_lookup(ExecutionContext *ctx, Value object, int lookupIndex)
@@ -810,7 +810,7 @@ uint __qmljs_equal(Value x, Value y, ExecutionContext *ctx)
     return false;
 }
 
-Value __qmljs_call_activation_property(ExecutionContext *context, String *name, Value *args, int argc)
+void __qmljs_call_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
 {
     Object *base;
     Value func = context->getPropertyAndBase(name, &base);
@@ -820,10 +820,16 @@ Value __qmljs_call_activation_property(ExecutionContext *context, String *name,
 
     Value thisObject = base ? Value::fromObject(base) : Value::undefinedValue();
 
-    if (o == context->engine->evalFunction && name->isEqualTo(context->engine->id_eval))
-        return static_cast<EvalFunction *>(o)->evalCall(context, thisObject, args, argc, true);
+    if (o == context->engine->evalFunction && name->isEqualTo(context->engine->id_eval)) {
+        Value res = static_cast<EvalFunction *>(o)->evalCall(context, thisObject, args, argc, true);
+        if (result)
+            *result = res;
+        return;
+    }
 
-    return o->call(context, thisObject, args, argc);
+    Value res = o->call(context, thisObject, args, argc);
+    if (result)
+        *result = res;
 }
 
 Value __qmljs_call_property(ExecutionContext *context, Value thisObject, String *name, Value *args, int argc)
@@ -927,10 +933,12 @@ Value __qmljs_call_value(ExecutionContext *context, Value thisObject, Value func
     return o->call(context, thisObject, args, argc);
 }
 
-Value __qmljs_construct_activation_property(ExecutionContext *context, String *name, Value *args, int argc)
+void __qmljs_construct_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
 {
     Value func = context->getProperty(name);
-    return __qmljs_construct_value(context, func, args, argc);
+    Value res = __qmljs_construct_value(context, func, args, argc);
+    if (result)
+        *result = res;
 }
 
 Value __qmljs_construct_value(ExecutionContext *context, Value func, Value *args, int argc)
index 579e832..786deb0 100644 (file)
@@ -91,13 +91,13 @@ struct ExecutionEngine;
 extern "C" {
 
 // context
-Value __qmljs_call_activation_property(ExecutionContext *, String *name, Value *args, int argc);
+void __qmljs_call_activation_property(ExecutionContext *, Value *result, String *name, Value *args, int argc);
 Value __qmljs_call_property(ExecutionContext *context, Value that, String *name, Value *args, int argc);
 Value __qmljs_call_property_lookup(ExecutionContext *context, Value thisObject, uint index, Value *args, int argc);
 Value __qmljs_call_element(ExecutionContext *context, Value that, Value index, Value *args, int argc);
 Value __qmljs_call_value(ExecutionContext *context, Value thisObject, Value func, Value *args, int argc);
 
-Value __qmljs_construct_activation_property(ExecutionContext *, String *name, Value *args, int argc);
+void __qmljs_construct_activation_property(ExecutionContext *, Value *result, String *name, Value *args, int argc);
 Value __qmljs_construct_property(ExecutionContext *context, Value base, String *name, Value *args, int argc);
 Value __qmljs_construct_value(ExecutionContext *context, Value func, Value *args, int argc);
 
@@ -165,10 +165,10 @@ Value __qmljs_new_object(ExecutionContext *ctx);
 Value __qmljs_new_boolean_object(ExecutionContext *ctx, bool boolean);
 Value __qmljs_new_number_object(ExecutionContext *ctx, double n);
 Value __qmljs_new_string_object(ExecutionContext *ctx, String *string);
-void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, Value value);
+void __qmljs_set_activation_property(ExecutionContext *ctx, String *name, const Value *value);
 void __qmljs_set_property(ExecutionContext *ctx, Value object, String *name, Value value);
 Value __qmljs_get_property(ExecutionContext *ctx, Value object, String *name);
-Value __qmljs_get_activation_property(ExecutionContext *ctx, String *name);
+void __qmljs_get_activation_property(ExecutionContext *ctx, Value *result, String *name);
 
 Value __qmljs_get_property_lookup(ExecutionContext *ctx, Value object, int lookupIndex);
 void __qmljs_set_property_lookup(ExecutionContext *ctx, Value object, int lookupIndex, Value value);
index 17cf824..e3580fc 100644 (file)
@@ -716,6 +716,11 @@ void Codegen::move(IR::Expr *target, IR::Expr *source, IR::AluOp op)
         _block->MOVE(_block->TEMP(t), source);
         source = _block->TEMP(t);
     }
+    if (target->asName() && source->asConst()) {
+        unsigned t = _block->newTemp();
+        _block->MOVE(_block->TEMP(t), source);
+        source = _block->TEMP(t);
+    }
 
     _block->MOVE(target, source, op);
 }
index 1e98c02..6460885 100644 (file)
@@ -584,7 +584,7 @@ void InstructionSelection::getActivationProperty(const QString &name, IR::Temp *
     Q_UNREACHABLE();
 }
 
-void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
+void InstructionSelection::setActivationProperty(IR::Temp *source, const QString &targetName)
 {
     llvm::Value *name = getIdentifier(targetName);
     llvm::Value *src = toValuePtr(source);
index ec5ace3..f306528 100644 (file)
@@ -110,7 +110,7 @@ public: // methods from InstructionSelection:
     virtual void loadString(const QString &str, IR::Temp *targetTemp);
     virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *targetTemp);
     virtual void getActivationProperty(const QString &name, IR::Temp *temp);
-    virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
+    virtual void setActivationProperty(IR::Temp *source, const QString &targetName);
     virtual void initClosure(IR::Closure *closure, IR::Temp *target);
     virtual void getProperty(IR::Temp *sourceBase, const QString &sourceName, IR::Temp *target);
     virtual void setProperty(IR::Expr *source, IR::Temp *targetBase, const QString &targetName);
index 3a8fef3..c2f1811 100644 (file)
@@ -668,13 +668,13 @@ void InstructionSelection::loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *target
 void InstructionSelection::getActivationProperty(const QString &name, IR::Temp *temp)
 {
     String *propertyName = identifier(name);
-    generateFunctionCall(temp, __qmljs_get_activation_property, Assembler::ContextRegister, propertyName);
+    generateFunctionCall(Assembler::Void, __qmljs_get_activation_property, Assembler::ContextRegister, Assembler::PointerToValue(temp), propertyName);
 }
 
-void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
+void InstructionSelection::setActivationProperty(IR::Temp *source, const QString &targetName)
 {
     String *propertyName = identifier(targetName);
-    generateFunctionCall(Assembler::Void, __qmljs_set_activation_property, Assembler::ContextRegister, propertyName, source);
+    generateFunctionCall(Assembler::Void, __qmljs_set_activation_property, Assembler::ContextRegister, propertyName, Assembler::PointerToValue(source));
 }
 
 void InstructionSelection::initClosure(IR::Closure *closure, IR::Temp *target)
@@ -990,7 +990,9 @@ void InstructionSelection::callRuntimeMethodImp(IR::Temp *result, const char* na
     assert(baseName != 0);
 
     int argc = prepareVariableArguments(args);
-    _as->generateFunctionCallImp(result, name, method, Assembler::ContextRegister, identifier(*baseName->id), baseAddressForCallArguments(), Assembler::TrustedImm32(argc));
+    _as->generateFunctionCallImp(Assembler::Void, name, method, Assembler::ContextRegister, Assembler::PointerToValue(result),
+                                 identifier(*baseName->id), baseAddressForCallArguments(),
+                                 Assembler::TrustedImm32(argc));
 }
 
 
index da5486e..7b42f11 100644 (file)
@@ -214,10 +214,12 @@ public:
 
     void loadArgument(PointerToValue temp, RegisterID dest)
     {
-        assert(temp.value);
-
-        Pointer addr = loadTempAddress(dest, temp.value);
-        loadArgument(addr, dest);
+        if (!temp.value) {
+            loadArgument(TrustedImmPtr(0), dest);
+        } else {
+            Pointer addr = loadTempAddress(dest, temp.value);
+            loadArgument(addr, dest);
+        }
     }
 
 #ifdef VALUE_FITS_IN_REGISTER
@@ -707,7 +709,7 @@ protected:
     virtual void loadString(const QString &str, IR::Temp *targetTemp);
     virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *targetTemp);
     virtual void getActivationProperty(const QString &name, IR::Temp *temp);
-    virtual void setActivationProperty(IR::Expr *source, const QString &targetName);
+    virtual void setActivationProperty(IR::Temp *source, const QString &targetName);
     virtual void initClosure(IR::Closure *closure, IR::Temp *target);
     virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target);
     virtual void setProperty(IR::Expr *source, IR::Temp *targetBase, const QString &targetName);
@@ -766,8 +768,7 @@ private:
 
     int prepareVariableArguments(IR::ExprList* args);
 
-    typedef VM::Value (*ActivationMethod)(VM::ExecutionContext *, VM::String *name, VM::Value *args, int argc);
-    typedef VM::Value (*BuiltinMethod)(VM::ExecutionContext *, VM::Value *args, int argc);
+    typedef void (*ActivationMethod)(VM::ExecutionContext *, VM::Value *result, VM::String *name, VM::Value *args, int argc);
     void callRuntimeMethodImp(IR::Temp *result, const char* name, ActivationMethod method, IR::Expr *base, IR::ExprList *args);
 #define callRuntimeMethod(result, function, ...) \
     callRuntimeMethodImp(result, isel_stringIfy(function), function, __VA_ARGS__)
index e47f349..2eb1b1d 100644 (file)
@@ -73,8 +73,8 @@ void InstructionSelection::visitMove(IR::Move *s)
 {
     if (s->op == IR::OpInvalid) {
         if (IR::Name *n = s->target->asName()) {
-            if (s->source->asTemp() || s->source->asConst()) {
-                setActivationProperty(s->source, *n->id);
+            if (s->source->asTemp()) {
+                setActivationProperty(s->source->asTemp(), *n->id);
                 return;
             }
         } else if (IR::Temp *t = s->target->asTemp()) {
index 5a0e828..d135cd3 100644 (file)
@@ -126,7 +126,7 @@ public: // to implement by subclasses:
     virtual void loadString(const QString &str, IR::Temp *targetTemp) = 0;
     virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Temp *targetTemp) = 0;
     virtual void getActivationProperty(const QString &name, IR::Temp *temp) = 0;
-    virtual void setActivationProperty(IR::Expr *source, const QString &targetName) = 0;
+    virtual void setActivationProperty(IR::Temp *source, const QString &targetName) = 0;
     virtual void initClosure(IR::Closure *closure, IR::Temp *target) = 0;
     virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target) = 0;
     virtual void setProperty(IR::Expr *source, IR::Temp *targetBase, const QString &targetName) = 0;