diff options
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arraydata_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 31 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context_p.h | 70 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4managed_p.h | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4memberdata.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4memberdata_p.h | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexp.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 5 | ||||
-rw-r--r-- | src/qml/memory/qv4heap_p.h | 14 | ||||
-rw-r--r-- | src/qml/memory/qv4mm_p.h | 4 |
18 files changed, 123 insertions, 78 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index f4afe46fcb..74c83b1940 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -143,13 +143,13 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt Scoped<ArrayData> newData(scope); if (newType < Heap::ArrayData::Sparse) { Heap::SimpleArrayData *n = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size); - new (n) Heap::SimpleArrayData; + n->init(); n->offset = 0; n->len = d ? d->d()->len : 0; newData = n; } else { Heap::SparseArrayData *n = scope.engine->memoryManager->allocManaged<SparseArrayData>(size); - new (n) Heap::SparseArrayData; + n->init(); newData = n; } newData->setAlloc(alloc); diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h index 8ad4704227..d7ee4798b0 100644 --- a/src/qml/jsruntime/qv4arraydata_p.h +++ b/src/qml/jsruntime/qv4arraydata_p.h @@ -133,6 +133,7 @@ struct ArrayData : public Base { } }; +Q_STATIC_ASSERT(std::is_trivial<ArrayData>::value); struct SimpleArrayData : public ArrayData { uint mappedIndex(uint index) const { return (index + offset) % alloc; } @@ -152,6 +153,7 @@ struct SimpleArrayData : public ArrayData { return attrs ? attrs[i] : Attr_Data; } }; +Q_STATIC_ASSERT(std::is_trivial<SimpleArrayData>::value); struct SparseArrayData : public ArrayData { inline ~SparseArrayData(); diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 1abaca3dd1..390a5e7d7a 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -61,8 +61,9 @@ Heap::CallContext *ExecutionContext::newCallContext(const FunctionObject *functi { Q_ASSERT(function->function()); - Heap::CallContext *c = d()->engine->memoryManager->allocManaged<CallContext>(requiredMemoryForExecutionContect(function, callData->argc)); - new (c) Heap::CallContext(d()->engine, Heap::ExecutionContext::Type_CallContext); + Heap::CallContext *c = d()->engine->memoryManager->allocManaged<CallContext>( + requiredMemoryForExecutionContect(function, callData->argc)); + c->init(d()->engine, Heap::ExecutionContext::Type_CallContext); c->function = function->d(); @@ -160,28 +161,16 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable) activation->__defineOwnProperty__(scope.engine, name, desc, attrs); } - -Heap::GlobalContext::GlobalContext(ExecutionEngine *eng) - : Heap::ExecutionContext(eng, Heap::ExecutionContext::Type_GlobalContext) +void Heap::GlobalContext::init(ExecutionEngine *eng) { + Heap::ExecutionContext::init(eng, Heap::ExecutionContext::Type_GlobalContext); global = eng->globalObject->d(); } -Heap::WithContext::WithContext(ExecutionContext *outerContext, Object *with) - : Heap::ExecutionContext(outerContext->engine, Heap::ExecutionContext::Type_WithContext) -{ - outer = outerContext; - callData = outer->callData; - lookups = outer->lookups; - constantTable = outer->constantTable; - compilationUnit = outer->compilationUnit; - - withObject = with; -} - -Heap::CatchContext::CatchContext(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue) - : Heap::ExecutionContext(outerContext->engine, Heap::ExecutionContext::Type_CatchContext) +void Heap::CatchContext::init(ExecutionContext *outerContext, String *exceptionVarName, + const Value &exceptionValue) { + Heap::ExecutionContext::init(outerContext->engine, Heap::ExecutionContext::Type_CatchContext); outer = outerContext; strictMode = outer->strictMode; callData = outer->callData; @@ -193,9 +182,9 @@ Heap::CatchContext::CatchContext(ExecutionContext *outerContext, String *excepti this->exceptionValue = exceptionValue; } -Heap::QmlContext::QmlContext(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml) - : Heap::ExecutionContext(outerContext->engine(), Heap::ExecutionContext::Type_QmlContext) +void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml) { + Heap::ExecutionContext::init(outerContext->engine(), Heap::ExecutionContext::Type_QmlContext); outer = outerContext->d(); strictMode = false; callData = outer->callData; diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 713b2b6412..ffedf737ce 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -101,7 +101,20 @@ struct ExecutionContext : Base { Type_CallContext = 0x6 }; - inline ExecutionContext(ExecutionEngine *engine, ContextType t); + void init(ExecutionEngine *engine, ContextType t) + { + Base::init(); + + callData = nullptr; + this->engine = engine; + outer = nullptr; + lookups = nullptr; + constantTable = nullptr; + compilationUnit = nullptr; + type = t; + strictMode = false; + lineNumber = -1; + } CallData *callData; @@ -115,25 +128,14 @@ struct ExecutionContext : Base { bool strictMode : 8; int lineNumber; }; - -inline -ExecutionContext::ExecutionContext(ExecutionEngine *engine, ContextType t) - : engine(engine) - , lookups(nullptr) - , constantTable(nullptr) - , compilationUnit(nullptr) - , type(t) - , strictMode(false) - , lineNumber(-1) -{ - outer = nullptr; -} - +Q_STATIC_ASSERT(std::is_trivial<ExecutionContext>::value); struct CallContext : ExecutionContext { - CallContext(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext) - : ExecutionContext(engine, t) + static CallContext createOnStack(ExecutionEngine *v4); + + void init(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext) { + ExecutionContext::init(engine, t); function = 0; locals = 0; activation = 0; @@ -143,27 +145,43 @@ struct CallContext : ExecutionContext { Value *locals; Pointer<Object> activation; }; +Q_STATIC_ASSERT(std::is_trivial<CallContext>::value); struct GlobalContext : ExecutionContext { - GlobalContext(ExecutionEngine *engine); + void init(ExecutionEngine *engine); Pointer<Object> global; }; +Q_STATIC_ASSERT(std::is_trivial<GlobalContext>::value); struct CatchContext : ExecutionContext { - CatchContext(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue); + void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue); Pointer<String> exceptionVarName; Value exceptionValue; }; +Q_STATIC_ASSERT(std::is_trivial<CatchContext>::value); struct WithContext : ExecutionContext { - WithContext(ExecutionContext *outerContext, Object *with); + void init(ExecutionContext *outerContext, Object *with) + { + Heap::ExecutionContext::init(outerContext->engine, Heap::ExecutionContext::Type_WithContext); + outer = outerContext; + callData = outer->callData; + lookups = outer->lookups; + constantTable = outer->constantTable; + compilationUnit = outer->compilationUnit; + + withObject = with; + } + Pointer<Object> withObject; }; +Q_STATIC_ASSERT(std::is_trivial<WithContext>::value); struct QmlContextWrapper; struct QmlContext : ExecutionContext { - QmlContext(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml); + void init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml); + Pointer<QmlContextWrapper> qml; }; @@ -280,6 +298,16 @@ inline const WithContext *ExecutionContext::asWithContext() const return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0; } +inline Heap::CallContext Heap::CallContext::createOnStack(ExecutionEngine *v4) +{ + Heap::CallContext ctxt; + memset(&ctxt, 0, sizeof(Heap::CallContext)); + ctxt.mm_data = 0; + ctxt.setVtable(QV4::CallContext::staticVTable()); + ctxt.init(v4); + return ctxt; +} + /* Function *f, int argc */ #define requiredMemoryForExecutionContect(f, argc) \ ((sizeof(CallContext::Data) + 7) & ~7) + sizeof(Value) * (f->varCount() + qMax((uint)argc, f->formalParameterCount())) + sizeof(CallData) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index f8110d29f6..e81292f598 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -488,8 +488,9 @@ void ExecutionEngine::setProfiler(Profiling::Profiler *profiler) void ExecutionEngine::initRootContext() { Scope scope(this); - Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(sizeof(GlobalContext::Data) + sizeof(CallData))); - new (r->d()) GlobalContext::Data(this); + Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>( + sizeof(GlobalContext::Data) + sizeof(CallData))); + r->d_unchecked()->init(this); r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1); r->d()->callData->tag = QV4::Value::Integer_Type_Internal; r->d()->callData->argc = 0; @@ -572,7 +573,7 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int leng if (length) { size_t size = sizeof(Heap::ArrayData) + (length-1)*sizeof(Value); Heap::SimpleArrayData *d = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size); - new (d) Heap::SimpleArrayData; + d->init(); d->alloc = length; d->type = Heap::ArrayData::Simple; d->offset = 0; diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index caabee322a..300e538d3d 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -73,7 +73,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, } // duplicate arguments, need some trick to store them MemoryManager *mm = engine->memoryManager; - arg = mm->alloc<String>(mm, arg->d(), engine->newString(QString(0xfffe))); + arg = mm->alloc<String>(mm, arg->d(), engine->newString(QString(0xfffe)), true); } } nFormals = compiledFunction->nFormals; @@ -105,7 +105,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr break; } // duplicate arguments, need some trick to store them - arg = engine->memoryManager->alloc<String>(engine->memoryManager, arg->d(), engine->newString(QString(0xfffe))); + arg = engine->memoryManager->alloc<String>(engine->memoryManager, arg->d(), engine->newString(QString(0xfffe)), true); } } nFormals = parameters.size(); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index df9f92b259..e160dd8a36 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -527,9 +527,7 @@ void SimpleScriptFunction::construct(const Managed *that, Scope &scope, CallData ScopedObject proto(scope, f->protoForConstructor()); callData->thisObject = v4->newObject(ic, proto); - CallContext::Data ctx(v4); - ctx.mm_data = 0; - ctx.setVtable(CallContext::staticVTable()); + CallContext::Data ctx = CallContext::Data::createOnStack(v4); ctx.strictMode = f->strictMode(); ctx.callData = callData; ctx.function = f->d(); @@ -568,9 +566,7 @@ void SimpleScriptFunction::call(const Managed *that, Scope &scope, CallData *cal Scoped<SimpleScriptFunction> f(scope, static_cast<const SimpleScriptFunction *>(that)); - CallContext::Data ctx(v4); - ctx.mm_data = 0; - ctx.setVtable(CallContext::staticVTable()); + CallContext::Data ctx = CallContext::Data::createOnStack(v4); ctx.strictMode = f->strictMode(); ctx.callData = callData; ctx.function = f->d(); @@ -626,9 +622,7 @@ void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData ExecutionContextSaver ctxSaver(scope); - CallContext::Data ctx(v4); - ctx.mm_data = 0; - ctx.setVtable(CallContext::staticVTable()); + CallContext::Data ctx = CallContext::Data::createOnStack(v4); ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? ctx.callData = callData; v4->pushContext(&ctx); @@ -649,9 +643,7 @@ void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *c ExecutionContextSaver ctxSaver(scope); - CallContext::Data ctx(v4); - ctx.mm_data = 0; - ctx.setVtable(CallContext::staticVTable()); + CallContext::Data ctx = CallContext::Data::createOnStack(v4); ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context? ctx.callData = callData; v4->pushContext(&ctx); diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h index 1109760fc0..764a8e7f3f 100644 --- a/src/qml/jsruntime/qv4managed_p.h +++ b/src/qml/jsruntime/qv4managed_p.h @@ -85,7 +85,12 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {} static const QV4::VTable static_vtbl; \ static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \ V4_MANAGED_SIZE_TEST \ - QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); } + QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \ + QV4::Heap::DataClass *d() const { \ + QV4::Heap::DataClass *dptr = d_unchecked(); \ + if (std::is_trivial<QV4::Heap::DataClass>::value) dptr->_checkIsInitialized(); \ + return dptr; \ + } #define V4_MANAGED(DataClass, superClass) \ private: \ diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp index 62e4f0a14d..5646a44891 100644 --- a/src/qml/jsruntime/qv4memberdata.cpp +++ b/src/qml/jsruntime/qv4memberdata.cpp @@ -58,9 +58,9 @@ static Heap::MemberData *reallocateHelper(ExecutionEngine *e, Heap::MemberData * Scope scope(e); Scoped<MemberData> newMemberData(scope, e->memoryManager->allocManaged<MemberData>(alloc)); if (old) - memcpy(newMemberData->d(), old, sizeof(Heap::MemberData) + old->size * sizeof(Value)); + memcpy(newMemberData->d_unchecked(), old, sizeof(Heap::MemberData) + old->size * sizeof(Value)); else - new (newMemberData->d()) Heap::MemberData; + newMemberData->d_unchecked()->init(); newMemberData->d()->size = n; return newMemberData->d(); } diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h index 2742e0b212..41da730428 100644 --- a/src/qml/jsruntime/qv4memberdata_p.h +++ b/src/qml/jsruntime/qv4memberdata_p.h @@ -66,6 +66,7 @@ struct MemberData : Base { }; Value data[1]; }; +Q_STATIC_ASSERT(std::is_trivial<MemberData>::value); } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index eda7774f90..54ce2ea60d 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -68,7 +68,7 @@ namespace QV4 { namespace Heap { struct Object : Base { - inline Object() {} + inline Object() { Base::init(); } const Value *propertyData(uint index) const { if (index < inlineMemberSize) return reinterpret_cast<const Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; } Value *propertyData(uint index) { if (index < inlineMemberSize) return reinterpret_cast<Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; } @@ -90,7 +90,12 @@ struct Object : Base { static const QV4::ObjectVTable static_vtbl; \ static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ V4_MANAGED_SIZE_TEST \ - Data *d() const { return static_cast<Data *>(m()); } + Data *d_unchecked() const { return static_cast<Data *>(m()); } \ + Data *d() const { \ + Data *dptr = d_unchecked(); \ + if (std::is_trivial<Data>::value) dptr->_checkIsInitialized(); \ + return dptr; \ + } #define V4_OBJECT2(DataClass, superClass) \ private: \ @@ -103,7 +108,12 @@ struct Object : Base { static const QV4::ObjectVTable static_vtbl; \ static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \ V4_MANAGED_SIZE_TEST \ - QV4::Heap::DataClass *d() const { return static_cast<QV4::Heap::DataClass *>(m()); } + QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \ + QV4::Heap::DataClass *d() const { \ + QV4::Heap::DataClass *dptr = d_unchecked(); \ + if (std::is_trivial<QV4::Heap::DataClass>::value) dptr->_checkIsInitialized(); \ + return dptr; \ + } #define V4_INTERNALCLASS(c) \ static QV4::InternalClass *defaultInternalClass(QV4::ExecutionEngine *e) \ diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index af5355c964..6d6d446ca2 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -95,6 +95,8 @@ Heap::RegExp::RegExp(ExecutionEngine* engine, const QString &pattern, bool ignor , ignoreCase(ignoreCase) , multiLine(multiline) { + Base::init(); + const char* error = 0; JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiline, &error); if (error) diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index b7a4c4f643..88c1286c61 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -555,7 +555,7 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Valu if (!pright->stringValue()->d()->length()) return pleft->asReturnedValue(); MemoryManager *mm = engine->memoryManager; - return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); + return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d(), true))->asReturnedValue(); } double x = RuntimeHelpers::toNumber(pleft); double y = RuntimeHelpers::toNumber(pright); @@ -572,7 +572,7 @@ QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Valu if (!right.stringValue()->d()->length()) return left.asReturnedValue(); MemoryManager *mm = engine->memoryManager; - return (mm->alloc<String>(mm, left.stringValue()->d(), right.stringValue()->d()))->asReturnedValue(); + return (mm->alloc<String>(mm, left.stringValue()->d(), right.stringValue()->d(), true))->asReturnedValue(); } Scope scope(engine); @@ -590,7 +590,7 @@ QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Valu if (!pright->stringValue()->d()->length()) return pleft->asReturnedValue(); MemoryManager *mm = engine->memoryManager; - return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue(); + return (mm->alloc<String>(mm, pleft->stringValue()->d(), pright->stringValue()->d(), true))->asReturnedValue(); } void Runtime::method_setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value) diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index 3901514326..8bc867e2cd 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -77,6 +77,8 @@ bool String::isEqualTo(Managed *t, Managed *o) Heap::String::String(MemoryManager *mm, const QString &t) : mm(mm) { + Base::init(); + subtype = String::StringType_Unknown; text = const_cast<QString &>(t).data_ptr(); @@ -87,9 +89,11 @@ Heap::String::String(MemoryManager *mm, const QString &t) len = text->size; } -Heap::String::String(MemoryManager *mm, String *l, String *r) +Heap::String::String(MemoryManager *mm, String *l, String *r, bool) // TODO: remove the dummy bool when String is trivial : mm(mm) { + Base::init(); + subtype = String::StringType_Unknown; left = l; diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index ff42ab6471..f347ea8897 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -72,7 +72,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base { #ifndef V4_BOOTSTRAP String(MemoryManager *mm, const QString &text); - String(MemoryManager *mm, String *l, String *n); + String(MemoryManager *mm, String *l, String *n, bool dummy); ~String() { if (!largestSubLength && !text->ref.deref()) QStringData::deallocate(text); diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index d02d08f3e6..78cd4de9fb 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -427,11 +427,8 @@ public: template<typename T> Value &operator=(const Scoped<T> &t); - Value &operator=(const Value &v) { - _val = v._val; - return *this; - } }; +Q_STATIC_ASSERT(std::is_trivial<Value>::value); inline bool Value::isString() const { diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h index f38898b2ea..d15d14e463 100644 --- a/src/qml/memory/qv4heap_p.h +++ b/src/qml/memory/qv4heap_p.h @@ -54,6 +54,10 @@ #include <private/qv4global_p.h> #include <QSharedPointer> +// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their +// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below. +#undef QML_CHECK_INIT_DESTROY_CALLS + QT_BEGIN_NAMESPACE namespace QV4 { @@ -120,6 +124,16 @@ struct Q_QML_EXPORT Base { void *operator new(size_t, Managed *m) { return m; } void *operator new(size_t, Heap::Base *m) { return m; } void operator delete(void *, Heap::Base *) {} + + void init() { setInitialized(); } +#ifdef QML_CHECK_INIT_DESTROY_CALLS + bool _isInitialized; + void _checkIsInitialized() { Q_ASSERT(_isInitialized); } + void setInitialized() { Q_ASSERT(!_isInitialized); _isInitialized = true; } +#else + Q_ALWAYS_INLINE void _checkIsInitialized() {} + Q_ALWAYS_INLINE void setInitialized() {} +#endif }; template <typename T> diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index 026cbd8c6b..6db5b54760 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -276,7 +276,7 @@ public: { Scope scope(engine); Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2); + t->d_unchecked()->init(arg1, arg2); return t->d(); } @@ -285,7 +285,7 @@ public: { Scope scope(engine); Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data))); - (void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3); + t->d_unchecked()->init(arg1, arg2, arg3); return t->d(); } |