aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp4
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h2
-rw-r--r--src/qml/jsruntime/qv4context.cpp31
-rw-r--r--src/qml/jsruntime/qv4context_p.h70
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4managed_p.h7
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp4
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h1
-rw-r--r--src/qml/jsruntime/qv4object_p.h16
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp6
-rw-r--r--src/qml/jsruntime/qv4string.cpp6
-rw-r--r--src/qml/jsruntime/qv4string_p.h2
-rw-r--r--src/qml/jsruntime/qv4value_p.h5
-rw-r--r--src/qml/memory/qv4heap_p.h14
-rw-r--r--src/qml/memory/qv4mm_p.h4
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();
}