Skip to content

Commit

Permalink
QML: Make Heap::Object and all subclasses trivial
Browse files Browse the repository at this point in the history
GCC6 might dead-store-eliminate out our secret write to Base::mmdata,
because it expects all memory content to be "undefined" before
constructor calls. Clang might take the same approach if the constructor
of Heap::Object is removed.

By making these structs trivial, it also makes them memcpy-able.

Change-Id: I055b2ad28311b997fbe059849ebda4d5894eaa9b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
  • Loading branch information
Erik Verbruggen authored and Erik Verbruggen committed Oct 6, 2016
1 parent 1b90dc4 commit 3b14e2f
Show file tree
Hide file tree
Showing 75 changed files with 585 additions and 454 deletions.
3 changes: 2 additions & 1 deletion src/imports/localstorage/plugin.cpp
Expand Up @@ -110,8 +110,9 @@ namespace QV4 {
namespace Heap {
struct QQmlSqlDatabaseWrapper : public Object {
enum Type { Database, Query, Rows };
QQmlSqlDatabaseWrapper()
void init()
{
Object::init();
type = Database;
database = new QSqlDatabase;
version = new QString;
Expand Down
7 changes: 4 additions & 3 deletions src/particles/qquickv4particledata.cpp
Expand Up @@ -273,10 +273,11 @@ QT_BEGIN_NAMESPACE
struct QV4ParticleData : public QV4::Object
{
struct Data : QV4::Object::Data {
Data(QQuickParticleData *datum, QQuickParticleSystem* particleSystem)
: datum(datum)
, particleSystem(particleSystem)
void init(QQuickParticleData *datum, QQuickParticleSystem* particleSystem)
{
Object::init();
this->datum = datum;
this->particleSystem = particleSystem;
}
QQuickParticleData* datum;//TODO: Guard needed?
QQuickParticleSystem* particleSystem;
Expand Down
10 changes: 5 additions & 5 deletions src/qml/jsapi/qjsvalueiterator.cpp
Expand Up @@ -103,11 +103,11 @@ QJSValueIterator::QJSValueIterator(const QJSValue& object)
return;
QV4::Scope scope(v4);
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
it->d()->it.flags = QV4::ObjectIterator::NoFlags;
it->d()->it().flags = QV4::ObjectIterator::NoFlags;
QV4::ScopedString nm(scope);
QV4::Property nextProperty;
QV4::PropertyAttributes nextAttributes;
it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
it->d()->it().next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
d_ptr->nextName.set(v4, nm.asReturnedValue());
}

Expand Down Expand Up @@ -157,7 +157,7 @@ bool QJSValueIterator::next()
QV4::ScopedString nm(scope);
QV4::Property nextProperty;
QV4::PropertyAttributes nextAttributes;
it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
it->d()->it().next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
d_ptr->nextName.set(v4, nm.asReturnedValue());
return d_ptr->currentName.as<QV4::String>() || d_ptr->currentIndex != UINT_MAX;
}
Expand Down Expand Up @@ -231,11 +231,11 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
QV4::ScopedObject o(scope, QJSValuePrivate::getValue(&object));
d_ptr->iterator.set(v4, v4->newForEachIteratorObject(o));
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
it->d()->it.flags = QV4::ObjectIterator::NoFlags;
it->d()->it().flags = QV4::ObjectIterator::NoFlags;
QV4::ScopedString nm(scope);
QV4::Property nextProperty;
QV4::PropertyAttributes nextAttributes;
it->d()->it.next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
it->d()->it().next(nm.getRef(), &d_ptr->nextIndex, &nextProperty, &nextAttributes);
d_ptr->nextName.set(v4, nm.asReturnedValue());
return *this;
}
Expand Down
5 changes: 3 additions & 2 deletions src/qml/jsruntime/qv4argumentsobject.cpp
Expand Up @@ -45,9 +45,10 @@ using namespace QV4;

DEFINE_OBJECT_VTABLE(ArgumentsObject);

Heap::ArgumentsObject::ArgumentsObject(QV4::CallContext *context)
: fullyCreated(false)
void Heap::ArgumentsObject::init(QV4::CallContext *context)
{
Object::init();
fullyCreated = false;
this->context = context->d();
Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable());

Expand Down
22 changes: 11 additions & 11 deletions src/qml/jsruntime/qv4argumentsobject_p.h
Expand Up @@ -60,12 +60,12 @@ namespace QV4 {
namespace Heap {

struct ArgumentsGetterFunction : FunctionObject {
inline ArgumentsGetterFunction(QV4::ExecutionContext *scope, uint index);
inline void init(QV4::ExecutionContext *scope, uint index);
uint index;
};

struct ArgumentsSetterFunction : FunctionObject {
inline ArgumentsSetterFunction(QV4::ExecutionContext *scope, uint index);
inline void init(QV4::ExecutionContext *scope, uint index);
uint index;
};

Expand All @@ -75,7 +75,7 @@ struct ArgumentsObject : Object {
CalleePropertyIndex = 1,
CallerPropertyIndex = 3
};
ArgumentsObject(QV4::CallContext *context);
void init(QV4::CallContext *context);
Pointer<CallContext> context;
bool fullyCreated;
Pointer<MemberData> mappedArguments;
Expand All @@ -91,11 +91,11 @@ struct ArgumentsGetterFunction: FunctionObject
static void call(const Managed *that, Scope &scope, CallData *d);
};

inline
Heap::ArgumentsGetterFunction::ArgumentsGetterFunction(QV4::ExecutionContext *scope, uint index)
: Heap::FunctionObject(scope)
, index(index)
inline void
Heap::ArgumentsGetterFunction::init(QV4::ExecutionContext *scope, uint index)
{
Heap::FunctionObject::init(scope);
this->index = index;
}

struct ArgumentsSetterFunction: FunctionObject
Expand All @@ -106,11 +106,11 @@ struct ArgumentsSetterFunction: FunctionObject
static void call(const Managed *that, Scope &scope, CallData *callData);
};

inline
Heap::ArgumentsSetterFunction::ArgumentsSetterFunction(QV4::ExecutionContext *scope, uint index)
: Heap::FunctionObject(scope)
, index(index)
inline void
Heap::ArgumentsSetterFunction::init(QV4::ExecutionContext *scope, uint index)
{
Heap::FunctionObject::init(scope);
this->index = index;
}


Expand Down
12 changes: 7 additions & 5 deletions src/qml/jsruntime/qv4arraybuffer.cpp
Expand Up @@ -46,9 +46,9 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(ArrayBufferCtor);
DEFINE_OBJECT_VTABLE(ArrayBuffer);

Heap::ArrayBufferCtor::ArrayBufferCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("ArrayBuffer"))
void Heap::ArrayBufferCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QStringLiteral("ArrayBuffer"));
}

void ArrayBufferCtor::construct(const Managed *m, Scope &scope, CallData *callData)
Expand Down Expand Up @@ -94,8 +94,9 @@ ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
}


Heap::ArrayBuffer::ArrayBuffer(size_t length)
void Heap::ArrayBuffer::init(size_t length)
{
Object::init();
data = QTypedArrayData<char>::allocate(length + 1);
if (!data) {
data = 0;
Expand All @@ -106,9 +107,10 @@ Heap::ArrayBuffer::ArrayBuffer(size_t length)
memset(data->data(), 0, length + 1);
}

Heap::ArrayBuffer::ArrayBuffer(const QByteArray& array)
: data(const_cast<QByteArray&>(array).data_ptr())
void Heap::ArrayBuffer::init(const QByteArray& array)
{
Object::init();
data = const_cast<QByteArray&>(array).data_ptr();
data->ref.ref();
}

Expand Down
6 changes: 3 additions & 3 deletions src/qml/jsruntime/qv4arraybuffer_p.h
Expand Up @@ -60,12 +60,12 @@ namespace QV4 {
namespace Heap {

struct ArrayBufferCtor : FunctionObject {
ArrayBufferCtor(QV4::ExecutionContext *scope);
void init(QV4::ExecutionContext *scope);
};

struct Q_QML_PRIVATE_EXPORT ArrayBuffer : Object {
ArrayBuffer(size_t length);
ArrayBuffer(const QByteArray& array);
void init(size_t length);
void init(const QByteArray& array);
void destroy();
QTypedArrayData<char> *data;

Expand Down
4 changes: 2 additions & 2 deletions src/qml/jsruntime/qv4arraydata_p.h
Expand Up @@ -133,7 +133,7 @@ struct ArrayData : public Base {
}

};
Q_STATIC_ASSERT(std::is_trivial<ArrayData>::value);
V4_ASSERT_IS_TRIVIAL(ArrayData)

struct SimpleArrayData : public ArrayData {
uint mappedIndex(uint index) const { return (index + offset) % alloc; }
Expand All @@ -153,7 +153,7 @@ struct SimpleArrayData : public ArrayData {
return attrs ? attrs[i] : Attr_Data;
}
};
Q_STATIC_ASSERT(std::is_trivial<SimpleArrayData>::value);
V4_ASSERT_IS_TRIVIAL(SimpleArrayData)

struct SparseArrayData : public ArrayData {
void destroy() { delete sparse; }
Expand Down
4 changes: 2 additions & 2 deletions src/qml/jsruntime/qv4arrayobject.cpp
Expand Up @@ -49,9 +49,9 @@ using namespace QV4;

DEFINE_OBJECT_VTABLE(ArrayCtor);

Heap::ArrayCtor::ArrayCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("Array"))
void Heap::ArrayCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QStringLiteral("Array"));
}

void ArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData)
Expand Down
2 changes: 1 addition & 1 deletion src/qml/jsruntime/qv4arrayobject_p.h
Expand Up @@ -61,7 +61,7 @@ namespace QV4 {
namespace Heap {

struct ArrayCtor : FunctionObject {
ArrayCtor(QV4::ExecutionContext *scope);
void init(QV4::ExecutionContext *scope);
};

}
Expand Down
4 changes: 2 additions & 2 deletions src/qml/jsruntime/qv4booleanobject.cpp
Expand Up @@ -45,9 +45,9 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(BooleanCtor);
DEFINE_OBJECT_VTABLE(BooleanObject);

Heap::BooleanCtor::BooleanCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("Boolean"))
void Heap::BooleanCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QStringLiteral("Boolean"));
}

void BooleanCtor::construct(const Managed *, Scope &scope, CallData *callData)
Expand Down
2 changes: 1 addition & 1 deletion src/qml/jsruntime/qv4booleanobject_p.h
Expand Up @@ -61,7 +61,7 @@ namespace QV4 {
namespace Heap {

struct BooleanCtor : FunctionObject {
BooleanCtor(QV4::ExecutionContext *scope);
void init(QV4::ExecutionContext *scope);
};

}
Expand Down
10 changes: 5 additions & 5 deletions src/qml/jsruntime/qv4context_p.h
Expand Up @@ -128,7 +128,7 @@ struct ExecutionContext : Base {
bool strictMode : 8;
int lineNumber;
};
Q_STATIC_ASSERT(std::is_trivial<ExecutionContext>::value);
V4_ASSERT_IS_TRIVIAL(ExecutionContext)

struct CallContext : ExecutionContext {
static CallContext createOnStack(ExecutionEngine *v4);
Expand All @@ -145,20 +145,20 @@ struct CallContext : ExecutionContext {
Value *locals;
Pointer<Object> activation;
};
Q_STATIC_ASSERT(std::is_trivial<CallContext>::value);
V4_ASSERT_IS_TRIVIAL(CallContext)

struct GlobalContext : ExecutionContext {
void init(ExecutionEngine *engine);
Pointer<Object> global;
};
Q_STATIC_ASSERT(std::is_trivial<GlobalContext>::value);
V4_ASSERT_IS_TRIVIAL(GlobalContext)

struct CatchContext : ExecutionContext {
void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
Pointer<String> exceptionVarName;
Value exceptionValue;
};
Q_STATIC_ASSERT(std::is_trivial<CatchContext>::value);
V4_ASSERT_IS_TRIVIAL(CatchContext)

struct WithContext : ExecutionContext {
void init(ExecutionContext *outerContext, Object *with)
Expand All @@ -175,7 +175,7 @@ struct WithContext : ExecutionContext {

Pointer<Object> withObject;
};
Q_STATIC_ASSERT(std::is_trivial<WithContext>::value);
V4_ASSERT_IS_TRIVIAL(WithContext)

struct QmlContextWrapper;

Expand Down
4 changes: 2 additions & 2 deletions src/qml/jsruntime/qv4dataview.cpp
Expand Up @@ -49,9 +49,9 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(DataViewCtor);
DEFINE_OBJECT_VTABLE(DataView);

Heap::DataViewCtor::DataViewCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("DataView"))
void Heap::DataViewCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QStringLiteral("DataView"));
}

void DataViewCtor::construct(const Managed *, Scope &scope, CallData *callData)
Expand Down
4 changes: 2 additions & 2 deletions src/qml/jsruntime/qv4dataview_p.h
Expand Up @@ -60,11 +60,11 @@ namespace QV4 {
namespace Heap {

struct DataViewCtor : FunctionObject {
DataViewCtor(QV4::ExecutionContext *scope);
void init(QV4::ExecutionContext *scope);
};

struct DataView : Object {
DataView() {}
void init() { Object::init(); }
Pointer<ArrayBuffer> buffer;
uint byteLength;
uint byteOffset;
Expand Down
10 changes: 6 additions & 4 deletions src/qml/jsruntime/qv4dateobject.cpp
Expand Up @@ -634,13 +634,15 @@ static double getLocalTZA()

DEFINE_OBJECT_VTABLE(DateObject);

Heap::DateObject::DateObject(const QDateTime &date)
void Heap::DateObject::init(const QDateTime &date)
{
Object::init();
this->date = date.isValid() ? date.toMSecsSinceEpoch() : qt_qnan();
}

Heap::DateObject::DateObject(const QTime &time)
void Heap::DateObject::init(const QTime &time)
{
Object::init();
if (!time.isValid()) {
date = qt_qnan();
return;
Expand Down Expand Up @@ -668,9 +670,9 @@ QDateTime DateObject::toQDateTime() const

DEFINE_OBJECT_VTABLE(DateCtor);

Heap::DateCtor::DateCtor(QV4::ExecutionContext *scope)
: Heap::FunctionObject(scope, QStringLiteral("Date"))
void Heap::DateCtor::init(QV4::ExecutionContext *scope)
{
Heap::FunctionObject::init(scope, QStringLiteral("Date"));
}

void DateCtor::construct(const Managed *, Scope &scope, CallData *callData)
Expand Down
14 changes: 8 additions & 6 deletions src/qml/jsruntime/qv4dateobject_p.h
Expand Up @@ -63,24 +63,26 @@ namespace QV4 {
namespace Heap {

struct DateObject : Object {
DateObject()
void init()
{
Object::init();
date = qt_qnan();
}

DateObject(const Value &date)
void init(const Value &date)
{
Object::init();
this->date = date.toNumber();
}
DateObject(const QDateTime &date);
double date;
void init(const QDateTime &date);
void init(const QTime &time);

DateObject(const QTime &time);
double date;
};


struct DateCtor : FunctionObject {
DateCtor(QV4::ExecutionContext *scope);
void init(QV4::ExecutionContext *scope);
};

}
Expand Down

0 comments on commit 3b14e2f

Please sign in to comment.