summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJedrzej Nowacki <jedrzej.nowacki@nokia.com>2011-05-19 13:49:29 +0200
committerJedrzej Nowacki <jedrzej.nowacki@nokia.com>2011-05-25 10:56:26 +0200
commit41668e40943f596dc3f64b2ec827ed40d9e25408 (patch)
treef57dd312880f7377db22614422afa6e8571ec992
parent0c2df7df1efa698def81101e90cc04c9a6f7829a (diff)
Introduce QScriptContextPrivate Stack and Heap classes.
This is the first step to optimize QSCP class. We will apply some optimizations based on type of allocation of an instance.
-rw-r--r--src/script/api/qscriptclass.cpp2
-rw-r--r--src/script/api/qscriptcontext.cpp2
-rw-r--r--src/script/api/qscriptcontext_impl_p.h51
-rw-r--r--src/script/api/qscriptcontext_p.h49
-rw-r--r--src/script/api/qscriptengine.cpp8
-rw-r--r--src/script/api/qscriptfunction_p.h2
-rw-r--r--src/script/api/qscriptqobject.cpp20
-rw-r--r--src/script/api/qscriptv8objectwrapper_p.h2
8 files changed, 100 insertions, 36 deletions
diff --git a/src/script/api/qscriptclass.cpp b/src/script/api/qscriptclass.cpp
index 5f78cba..ad6d8ac 100644
--- a/src/script/api/qscriptclass.cpp
+++ b/src/script/api/qscriptclass.cpp
@@ -260,7 +260,7 @@ v8::Handle<v8::Value> QScriptClassObject::call(const v8::Arguments& args)
thisObject->SetPrototype(proto);
}
- QScriptContextPrivate qScriptContext(data->engine, &args, args.Holder(), thisObject);
+ QScriptContextPrivate::Stack qScriptContext(data->engine, &args, args.Holder(), thisObject);
QScriptContext *ctx = &qScriptContext;
Q_ASSERT(ctx == data->engine->currentContext());
diff --git a/src/script/api/qscriptcontext.cpp b/src/script/api/qscriptcontext.cpp
index 5647b9a..df6aa92 100644
--- a/src/script/api/qscriptcontext.cpp
+++ b/src/script/api/qscriptcontext.cpp
@@ -299,7 +299,7 @@ QScriptContext *QScriptContext::parentContext() const
QScriptContextPrivate **tail = &d_ptr->previous;
for (int i = 0; i < stacktrace->GetFrameCount(); ++i) {
v8::Local<v8::StackFrame> fr = stacktrace->GetFrame(i);
- *tail = new QScriptContextPrivate(d_ptr->parent, fr);
+ *tail = new QScriptContextPrivate::Heap(d_ptr->parent, fr);
tail = &((*tail)->previous);
}
}
diff --git a/src/script/api/qscriptcontext_impl_p.h b/src/script/api/qscriptcontext_impl_p.h
index fdf4a50..266f2d0 100644
--- a/src/script/api/qscriptcontext_impl_p.h
+++ b/src/script/api/qscriptcontext_impl_p.h
@@ -42,15 +42,15 @@
QT_BEGIN_NAMESPACE
-inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine)
- : q_ptr(this), engine(engine), arguments(0), accessorInfo(0), parent(engine->setCurrentQSContext(this)),
+inline QScriptContextPrivate::QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine)
+ : m_allocation(type), q_ptr(this), engine(engine), arguments(0), accessorInfo(0), parent(engine->setCurrentQSContext(this)),
previous(0) , hasArgumentGetter(false)
{
Q_ASSERT(engine);
}
-inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee, v8::Handle<v8::Object> customThisObject)
- : q_ptr(this), engine(engine), arguments(args), accessorInfo(0),
+inline QScriptContextPrivate::QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee, v8::Handle<v8::Object> customThisObject)
+ : m_allocation(type), q_ptr(this), engine(engine), arguments(args), accessorInfo(0),
context(v8::Persistent<v8::Context>::New(v8::Context::NewFunctionContext())),
inheritedScope(v8::Persistent<v8::Context>::New(v8::Context::GetCallerContext())),
parent(engine->setCurrentQSContext(this)), previous(0), m_thisObject(v8::Persistent<v8::Object>::New(customThisObject)),
@@ -61,19 +61,19 @@ inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine
context->Enter();
}
-inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor)
-: q_ptr(this), engine(engine), arguments(0), accessorInfo(accessor),
- context(v8::Persistent<v8::Context>::New(v8::Context::NewFunctionContext())),
- inheritedScope(v8::Persistent<v8::Context>::New(v8::Context::GetCallerContext())),
- parent(engine->setCurrentQSContext(this)), previous(0), hasArgumentGetter(false)
+inline QScriptContextPrivate::QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor)
+ : m_allocation(type), q_ptr(this), engine(engine), arguments(0), accessorInfo(accessor),
+ context(v8::Persistent<v8::Context>::New(v8::Context::NewFunctionContext())),
+ inheritedScope(v8::Persistent<v8::Context>::New(v8::Context::GetCallerContext())),
+ parent(engine->setCurrentQSContext(this)), previous(0), hasArgumentGetter(false)
{
Q_ASSERT(engine);
Q_ASSERT(parent);
context->Enter();
}
-inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine, v8::Handle<v8::Context> context)
- : q_ptr(this), engine(engine), arguments(0), accessorInfo(0),
+inline QScriptContextPrivate::QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, v8::Handle<v8::Context> context)
+ : m_allocation(type), q_ptr(this), engine(engine), arguments(0), accessorInfo(0),
context(v8::Persistent<v8::Context>::New(context)), parent(engine->setCurrentQSContext(this)),
previous(0), hasArgumentGetter(false)
{
@@ -82,8 +82,8 @@ inline QScriptContextPrivate::QScriptContextPrivate(QScriptEnginePrivate *engine
context->Enter();
}
-inline QScriptContextPrivate::QScriptContextPrivate(QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame)
- : q_ptr(this), engine(parent->engine), arguments(0), accessorInfo(0),
+inline QScriptContextPrivate::QScriptContextPrivate(const AllocationType type, QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame)
+ : m_allocation(type), q_ptr(this), engine(parent->engine), arguments(0), accessorInfo(0),
parent(parent), previous(0), frame(v8::Persistent<v8::StackFrame>::New(frame)), hasArgumentGetter(false)
{
Q_ASSERT(engine);
@@ -380,6 +380,31 @@ inline v8::Handle<v8::Value> QScriptContextPrivate::throwError(QScriptContext::E
return engine->throwException(exception);
}
+inline QScriptContextPrivate::Stack::Stack(QScriptEnginePrivate *engine) // the global context (member of QScriptEnginePrivate)
+ : QScriptContextPrivate(StackAllocation, engine)
+{}
+
+inline QScriptContextPrivate::Stack::Stack(QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee, v8::Handle<v8::Object> customThisObject) // native function context (on the stack)
+ : QScriptContextPrivate(StackAllocation, engine, args, callee, customThisObject)
+{}
+
+inline QScriptContextPrivate::Stack::Stack(QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor) // native acessors (on the stack)
+ : QScriptContextPrivate(StackAllocation, engine, accessor)
+{}
+
+inline QScriptContextPrivate::Heap::Heap(QScriptEnginePrivate *engine) // the global context (member of QScriptEnginePrivate)
+ : QScriptContextPrivate(HeapAllocation, engine)
+{}
+
+inline QScriptContextPrivate::Heap::Heap(QScriptEnginePrivate *engine, v8::Handle<v8::Context> context) // from QScriptEngine::pushContext
+ : QScriptContextPrivate(HeapAllocation, engine, context)
+{}
+
+inline QScriptContextPrivate::Heap::Heap(QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame) // internal, for js frame (allocated in parentContext())
+ : QScriptContextPrivate(HeapAllocation, parent, frame)
+{}
+
+
QT_END_NAMESPACE
diff --git a/src/script/api/qscriptcontext_p.h b/src/script/api/qscriptcontext_p.h
index 41df26f..daac674 100644
--- a/src/script/api/qscriptcontext_p.h
+++ b/src/script/api/qscriptcontext_p.h
@@ -50,15 +50,22 @@ class QScriptContext;
class QScriptContextPrivate : public QScriptContext
{
Q_DECLARE_PUBLIC(QScriptContext);
+
+protected:
+ enum AllocationType {HeapAllocation, StackAllocation};
+ inline QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine); // the global context (member of QScriptEnginePrivate)
+ inline QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee = v8::Handle<v8::Value>(), v8::Handle<v8::Object> customThisObject = v8::Handle<v8::Object>()); // native function context (on the stack)
+ inline QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor); // native acessors (on the stack)
+ inline QScriptContextPrivate(const AllocationType type, QScriptEnginePrivate *engine, v8::Handle<v8::Context> context); // from QScriptEngine::pushContext
+ inline QScriptContextPrivate(const AllocationType type, QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame); // internal, for js frame (allocated in parentContext())
+
public:
+ class Stack;
+ class Heap;
+
static QScriptContextPrivate *get(const QScriptContext *q) { Q_ASSERT(q->d_ptr); return q->d_ptr; }
static QScriptContext *get(QScriptContextPrivate *d) { return d->q_func(); }
- inline QScriptContextPrivate(QScriptEnginePrivate *engine); // the global context (member of QScriptEnginePrivate)
- inline QScriptContextPrivate(QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee = v8::Handle<v8::Value>(), v8::Handle<v8::Object> customThisObject = v8::Handle<v8::Object>()); // native function context (on the stack)
- inline QScriptContextPrivate(QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor); // native acessors (on the stack)
- inline QScriptContextPrivate(QScriptEnginePrivate *engine, v8::Handle<v8::Context> context); // from QScriptEngine::pushContext
- inline QScriptContextPrivate(QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame); // internal, for js frame (allocated in parentContext())
inline ~QScriptContextPrivate();
inline bool isGlobalContext() const { return !parent; }
@@ -84,6 +91,7 @@ public:
inline v8::Handle<v8::Value> throwError(Error error, const QString &text);
+ const AllocationType m_allocation;
QScriptContext* q_ptr;
QScriptEnginePrivate *engine;
const v8::Arguments *arguments;
@@ -106,6 +114,37 @@ private:
Q_DISABLE_COPY(QScriptContextPrivate)
};
+/**
+ \internal
+ Optimised context that use Local handles instead of persistent
+ \attention this class doesn't manage HandleScope it is left to user of this class
+ */
+class QScriptContextPrivate::Stack : public QScriptContextPrivate
+{
+public:
+ inline Stack(QScriptEnginePrivate *engine); // the global context (member of QScriptEnginePrivate)
+ inline Stack(QScriptEnginePrivate *engine, const v8::Arguments *args, v8::Handle<v8::Value> callee = v8::Handle<v8::Value>(), v8::Handle<v8::Object> customThisObject = v8::Handle<v8::Object>()); // native function context (on the stack)
+ inline Stack(QScriptEnginePrivate *engine, const v8::AccessorInfo *accessor); // native acessors (on the stack)
+ // Only base class is used so destructor here is pointless
+private:
+ // no heap allocation is allowed these operators are not defined
+ inline void *operator new(size_t);
+ inline void *operator new(size_t, void*);
+};
+
+/**
+ \internal
+ Context that use persistent handles, it would work on a heap as on a stack. It is a bit slower then Stack version
+ */
+class QScriptContextPrivate::Heap : public QScriptContextPrivate
+{
+public:
+ inline Heap(QScriptEnginePrivate *engine); // the global context (member of QScriptEnginePrivate)
+ inline Heap(QScriptEnginePrivate *engine, v8::Handle<v8::Context> context); // from QScriptEngine::pushContext
+ inline Heap(QScriptContextPrivate *parent, v8::Handle<v8::StackFrame> frame); // internal, for js frame (allocated in parentContext())
+ // Only base class is used so a destructor here is pointless
+};
+
QT_END_NAMESPACE
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index 7620274..8752cbd 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -704,7 +704,7 @@ QScriptEnginePrivate::QScriptEnginePrivate(QScriptEngine::ContextOwnership owner
qMetaTypeId<QObjectList>();
Q_ASSERT(!m_v8Context.IsEmpty());
- m_baseQsContext.reset(new QScriptContextPrivate(this));
+ m_baseQsContext.reset(new QScriptContextPrivate::Heap(this));
m_isolate->Exit();
}
@@ -759,7 +759,7 @@ class QScriptEnginePrivate::ProcessEventTimeoutThread : public QThread {
QScriptEnginePrivate *engine = static_cast<QScriptEnginePrivate *>(data);
//executed in the JS thread
if (engine->isEvaluating()) {
- QScriptContextPrivate qScriptContext(engine);
+ QScriptContextPrivate::Stack qScriptContext(engine);
qApp->processEvents();
}
}
@@ -866,7 +866,7 @@ QScriptContextPrivate *QScriptEnginePrivate::pushContext()
{
if (m_currentAgent)
m_currentAgent->pushContext();
- return new QScriptContextPrivate(this, v8::Context::NewFunctionContext());
+ return new QScriptContextPrivate::Heap(this, v8::Context::NewFunctionContext());
}
void QScriptEnginePrivate::popContext()
@@ -2104,7 +2104,7 @@ v8::Handle<v8::Value> QtTranslateFunctionQsTr(const v8::Arguments& arguments)
QString context;
// This engine should be always valid, because this function can be called if and only if the engine is still alive.
QScriptEnginePrivate *engine = static_cast<QScriptEnginePrivate*>(v8::Handle<v8::Object>::Cast(arguments.Data())->GetPointerFromInternalField(0));
- QScriptContextPrivate qScriptContext(engine, &arguments);
+ QScriptContextPrivate::Stack qScriptContext(engine, &arguments);
QScriptContext *ctx = qScriptContext.parentContext();
while (ctx) {
QString fn = QScriptContextInfo(ctx).fileName();
diff --git a/src/script/api/qscriptfunction_p.h b/src/script/api/qscriptfunction_p.h
index f3e4cdf..ca14bf9 100644
--- a/src/script/api/qscriptfunction_p.h
+++ b/src/script/api/qscriptfunction_p.h
@@ -84,7 +84,7 @@ v8::Handle<v8::Value> QtNativeFunctionCallback(const v8::Arguments& arguments)
T *data = reinterpret_cast<T *>(wrap->Value());
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate qScriptContext(engine, &arguments);
+ QScriptContextPrivate::Stack qScriptContext(engine, &arguments);
// When 'v' gets out of scope, it'll delete 'result'.
QScriptValue v = data->call(&qScriptContext);
diff --git a/src/script/api/qscriptqobject.cpp b/src/script/api/qscriptqobject.cpp
index be8efbb..64326d1 100644
--- a/src/script/api/qscriptqobject.cpp
+++ b/src/script/api/qscriptqobject.cpp
@@ -832,7 +832,7 @@ static v8::Handle<v8::Value> QtMetaPropertyGetter(v8::Local<v8::String> property
v8::Local<v8::Object> self = info.Holder();
QScriptQObjectData *data = QScriptQObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
v8::Local<v8::Value> error;
QObject *qobject = data->cppObject(&error);
@@ -871,7 +871,7 @@ static void QtMetaPropertySetter(v8::Local<v8::String> /*property*/,
v8::Local<v8::Object> self = info.Holder(); // This?
QScriptQObjectData *data = QScriptQObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
QObject *qobject = data->cppObject();
if (!qobject)
@@ -931,7 +931,7 @@ v8::Handle<v8::Value> QtDynamicPropertyGetter(v8::Local<v8::String> property,
v8::Local<v8::Object> self = info.Holder(); // This?
QScriptQObjectData *data = QScriptQObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
v8::Local<v8::Value> error;
QObject *qobject = data->cppObject(&error);
@@ -962,7 +962,7 @@ void QtDynamicPropertySetter(v8::Local<v8::String> property,
v8::Local<v8::Object> self = info.Holder(); // This?
QScriptQObjectData *data = QScriptQObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
QObject *qobject = data->cppObject();
if (!qobject)
@@ -995,7 +995,7 @@ v8::Handle<v8::Value> QtLazyPropertyGetter(v8::Local<v8::String> property,
return v8::Handle<v8::Value>(); //the QObject prototype is being used on another object.
QScriptQObjectData *data = QScriptQObjectData::get(self);
Q_ASSERT(engine == data->engine());
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
v8::Local<v8::Value> error;
QObject *qobject = data->cppObject(&error);
@@ -1077,7 +1077,7 @@ v8::Handle<v8::Value> QtMetaObjectPropertyGetter(v8::Local<v8::String> property,
v8::Local<v8::Object> self = info.Holder();
QtMetaObjectData *data = QtMetaObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
const QMetaObject *meta = data->metaObject();
QString propertyName = QScriptConverter::toString(property);
@@ -1109,7 +1109,7 @@ v8::Handle<v8::Array> QtMetaObjectEnumerator(const v8::AccessorInfo& info)
v8::Local<v8::Object> self = info.Holder();
QtMetaObjectData *data = QtMetaObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &info);
+ QScriptContextPrivate::Stack context(engine, &info);
const QMetaObject *meta = data->metaObject();
v8::Handle<v8::Array> names = v8::Array::New(0);
@@ -1129,7 +1129,7 @@ v8::Handle<v8::Value> QtMetaObjectCallback(const v8::Arguments& args)
v8::Local<v8::Object> self = args.Holder();
QtMetaObjectData *data = QtMetaObjectData::get(self);
QScriptEnginePrivate *engine = data->engine();
- QScriptContextPrivate context(engine, &args);
+ QScriptContextPrivate::Stack context(engine, &args);
// const QMetaObject *meta = data->metaObject();
// qDebug() << Q_FUNC_INFO << meta->className();
@@ -1304,7 +1304,7 @@ static v8::Handle<v8::Value> findChildCallback(const v8::Arguments& args)
return v8::Handle<v8::Value>(); //the QObject prototype is being used on another object.
QScriptQObjectData *data = QScriptQObjectData::get(self);
Q_ASSERT(engine == data->engine());
- QScriptContextPrivate context(engine, &args);
+ QScriptContextPrivate::Stack context(engine, &args);
v8::Local<v8::Value> error;
QObject *qobject = data->cppObject(&error);
@@ -1349,7 +1349,7 @@ static v8::Handle<v8::Value> findChildrenCallback(const v8::Arguments& args)
return v8::Handle<v8::Value>(); //the QObject prototype is being used on another object.
QScriptQObjectData *data = QScriptQObjectData::get(self);
Q_ASSERT(engine == data->engine());
- QScriptContextPrivate context(engine, &args);
+ QScriptContextPrivate::Stack context(engine, &args);
v8::Local<v8::Value> error;
QObject *qobject = data->cppObject(&error);
diff --git a/src/script/api/qscriptv8objectwrapper_p.h b/src/script/api/qscriptv8objectwrapper_p.h
index f4e0fed..64464e7 100644
--- a/src/script/api/qscriptv8objectwrapper_p.h
+++ b/src/script/api/qscriptv8objectwrapper_p.h
@@ -71,7 +71,7 @@ T *getDataPointer(const v8::Arguments& args)
#define QTSCRIPT_V8OBJECT_DATA_CALLBACK(arg, callback) \
v8::HandleScope handleScope; \
T *data = getDataPointer<T>(arg); \
- QScriptContextPrivate qScriptContext(data->engine, &arg); \
+ QScriptContextPrivate::Stack qScriptContext(data->engine, &arg); \
return handleScope.Close(callback);
#endif