aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-03-05 08:40:11 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-07 16:55:12 +0100
commitb8ca4132433c2d1eef0a6cda8be8a1754786702b (patch)
tree4ace1513d0aaaa09b98bcc39f2a4fb2e08e0d59d /src/qml/jsruntime
parentf836b9837dda09c09c2ee3307300998ca5dff5c4 (diff)
Better way of retrieving the prototype property for FunctionObjects
Make sure FunctionObjects always have the prototype property at index 0. This way we can speed up the instanceOf operator even more, and at the same time save 16-28 bytes of memory per FunctionObject. Change-Id: I8527bc8f9dc7b04a9db8395b5f05bab47ddc21ce Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h1
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp75
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h18
4 files changed, 31 insertions, 65 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 6b2d1e657b..18075139d2 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -283,7 +283,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
FunctionPrototype *functionPrototype = new (memoryManager) FunctionPrototype(InternalClass::create(this, FunctionPrototype::staticVTable(), objectPrototype));
functionClass = InternalClass::create(this, FunctionObject::staticVTable(), functionPrototype);
uint index;
- functionWithProtoClass = functionClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
+ functionClass = functionClass->addMember(id_prototype, Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == FunctionObject::Index_Prototype);
protoClass = objectClass->addMember(id_constructor, Attr_NotEnumerable, &index);
Q_ASSERT(index == FunctionObject::Index_ProtoConstructor);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index cbe9815d4f..14358c1bb6 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -210,7 +210,6 @@ public:
InternalClass *dateClass;
InternalClass *functionClass;
- InternalClass *functionWithProtoClass;
InternalClass *protoClass;
InternalClass *regExpClass;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index f0966492a9..9a3aa331dc 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -75,21 +75,17 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto)
- : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
+ : Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
init(name, createProto);
}
FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto)
- : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass)
+ : Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -101,8 +97,6 @@ FunctionObject::FunctionObject(ExecutionContext *scope, const ReturnedValue name
: Object(scope->engine->functionClass)
, scope(scope)
, function(0)
- , protoCacheClass(0)
- , protoCacheIndex(UINT_MAX)
{
Scope s(scope);
ScopedValue protectThis(s, this);
@@ -117,6 +111,7 @@ FunctionObject::FunctionObject(InternalClass *ic)
{
needsActivation = false;
strictMode = false;
+ memberData[Index_Prototype].value = Encode::undefined();
}
FunctionObject::~FunctionObject()
@@ -137,6 +132,9 @@ void FunctionObject::init(const StringRef n, bool createProto)
Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass));
proto->memberData[Index_ProtoConstructor].value = this->asReturnedValue();
memberData[Index_Prototype].value = proto.asReturnedValue();
+ } else {
+ // ### Empty or undefined?
+ memberData[Index_Prototype].value = Encode::undefined();
}
ScopedValue v(s, n.asReturnedValue());
@@ -158,13 +156,8 @@ ReturnedValue FunctionObject::newInstance()
ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
- ExecutionEngine *v4 = that->internalClass->engine;
- Scope scope(v4);
- Scoped<FunctionObject> f(scope, that, Scoped<FunctionObject>::Cast);
-
- InternalClass *ic = f->internalClassForConstructor();
- Scoped<Object> obj(scope, v4->newObject(ic));
- return obj.asReturnedValue();
+ that->internalClass->engine->currentContext()->throwTypeError();
+ return Encode::undefined();
}
ReturnedValue FunctionObject::call(Managed *, CallData *)
@@ -190,43 +183,6 @@ FunctionObject *FunctionObject::creatScriptFunction(ExecutionContext *scope, Fun
return new (scope->engine->memoryManager) SimpleScriptFunction(scope, function, createProto);
}
-ReturnedValue FunctionObject::protoProperty()
-{
- if (protoCacheClass != internalClass) {
- protoCacheClass = internalClass;
- protoCacheIndex = internalClass->find(internalClass->engine->id_prototype);
- }
- if (protoCacheIndex < UINT_MAX) {
- if (internalClass->propertyData.at(protoCacheIndex).isData()) {
- ReturnedValue v = memberData[protoCacheIndex].value.asReturnedValue();
- if (v != protoValue) {
- classForConstructor = 0;
- protoValue = v;
- }
- return v;
- }
- }
- classForConstructor = 0;
- return get(internalClass->engine->id_prototype);
-}
-
-InternalClass *FunctionObject::internalClassForConstructor()
-{
- // need to call this first to ensure we don't use a wrong class
- ReturnedValue proto = protoProperty();
- if (classForConstructor)
- return classForConstructor;
-
- Scope scope(internalClass->engine);
- ScopedObject p(scope, proto);
- if (p)
- classForConstructor = InternalClass::create(scope.engine, Object::staticVTable(), p.getPointer());
- else
- classForConstructor = scope.engine->objectClass;
-
- return classForConstructor;
-}
-
DEFINE_OBJECT_VTABLE(FunctionCtor);
FunctionCtor::FunctionCtor(ExecutionContext *scope)
@@ -395,7 +351,7 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
DEFINE_OBJECT_VTABLE(ScriptFunction);
ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function)
- : FunctionObject(scope, function->name(), true)
+ : SimpleScriptFunction(scope, function, true)
{
setVTable(staticVTable());
@@ -583,6 +539,19 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData)
return result.asReturnedValue();
}
+InternalClass *SimpleScriptFunction::internalClassForConstructor()
+{
+ ReturnedValue proto = protoProperty();
+ InternalClass *classForConstructor;
+ Scope scope(internalClass->engine);
+ ScopedObject p(scope, proto);
+ if (p)
+ classForConstructor = InternalClass::create(scope.engine, Object::staticVTable(), p.getPointer());
+ else
+ classForConstructor = scope.engine->objectClass;
+
+ return classForConstructor;
+}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 3f432c2f26..a08dc603ff 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -116,10 +116,6 @@ struct Q_QML_EXPORT FunctionObject: Object {
unsigned int formalParameterCount() { return function ? function->compiledFunction->nFormals : 0; }
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
Function *function;
- InternalClass *protoCacheClass;
- uint protoCacheIndex;
- ReturnedValue protoValue;
- InternalClass *classForConstructor;
FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto = false);
FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false);
@@ -141,8 +137,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
static FunctionObject *creatScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
- ReturnedValue protoProperty();
- InternalClass *internalClassForConstructor();
+ ReturnedValue protoProperty() { return memberData[Index_Prototype].value.asReturnedValue(); }
protected:
FunctionObject(InternalClass *ic);
@@ -213,22 +208,25 @@ struct IndexedBuiltinFunction: FunctionObject
};
-struct ScriptFunction: FunctionObject {
+struct SimpleScriptFunction: FunctionObject {
V4_OBJECT
- ScriptFunction(ExecutionContext *scope, Function *function);
+ SimpleScriptFunction(ExecutionContext *scope, Function *function, bool createProto);
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
+
+ InternalClass *internalClassForConstructor();
};
-struct SimpleScriptFunction: FunctionObject {
+struct ScriptFunction: SimpleScriptFunction {
V4_OBJECT
- SimpleScriptFunction(ExecutionContext *scope, Function *function, bool createProto);
+ ScriptFunction(ExecutionContext *scope, Function *function);
static ReturnedValue construct(Managed *, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
};
+
struct BoundFunction: FunctionObject {
V4_OBJECT
FunctionObject *target;