diff options
author | Jedrzej Nowacki <jedrzej.nowacki@nokia.com> | 2011-05-19 13:49:29 +0200 |
---|---|---|
committer | Jedrzej Nowacki <jedrzej.nowacki@nokia.com> | 2011-05-25 10:56:26 +0200 |
commit | 41668e40943f596dc3f64b2ec827ed40d9e25408 (patch) | |
tree | f57dd312880f7377db22614422afa6e8571ec992 | |
parent | 0c2df7df1efa698def81101e90cc04c9a6f7829a (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.cpp | 2 | ||||
-rw-r--r-- | src/script/api/qscriptcontext.cpp | 2 | ||||
-rw-r--r-- | src/script/api/qscriptcontext_impl_p.h | 51 | ||||
-rw-r--r-- | src/script/api/qscriptcontext_p.h | 49 | ||||
-rw-r--r-- | src/script/api/qscriptengine.cpp | 8 | ||||
-rw-r--r-- | src/script/api/qscriptfunction_p.h | 2 | ||||
-rw-r--r-- | src/script/api/qscriptqobject.cpp | 20 | ||||
-rw-r--r-- | src/script/api/qscriptv8objectwrapper_p.h | 2 |
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 |