From 87f016ea9eddc874d5cba7d79d0a487d5ef61761 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Sat, 4 Feb 2017 15:12:54 +0200 Subject: Add Q_ALLOCA_VAR, Q_ALLOCA_DECLARE and Q_ALLOCA_ASSIGN macros Define Q_ALLOCA_VAR macro to be used instead of #ifdeffing the occurrences of alloca() in case it's not supported. Q_ALLOCA_DECLARE and Q_ALLOCA_ASSIGN macros separate memory allocation from the declaration and RAII. Change-Id: Idc7551642c48a968a44bcade14d84800a3a1270e Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/qml/compiler/qv4compiler.cpp | 2 +- src/qml/jit/qv4regalloc.cpp | 2 +- src/qml/jsruntime/qv4regexpobject.cpp | 2 +- src/qml/jsruntime/qv4stringobject.cpp | 4 ++-- src/qml/jsruntime/qv4vme_moth.cpp | 4 +--- src/qml/qml/qqmlvaluetypewrapper.cpp | 4 +++- src/qml/qtqmlglobal_p.h | 40 +++++++++++++++++++++++++++++++++++ src/qml/types/qqmllistmodel.cpp | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index cd822a2614..9cfac4a676 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -220,7 +220,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO registerString(*f->locals.at(i)); } - CompiledData::LEUInt32 *functionOffsets = reinterpret_cast(alloca(irModule->functions.size() * sizeof(CompiledData::LEUInt32))); + Q_ALLOCA_VAR(CompiledData::LEUInt32, functionOffsets, irModule->functions.size() * sizeof(CompiledData::LEUInt32)); uint jsClassDataOffset = 0; char *dataPtr; diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index d5da863ee0..e5abaa7458 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -1575,7 +1575,7 @@ static void longestAvailableReg(int *nextUses, int nextUseCount, int ®, int & #define CALLOC_ON_STACK(ty, ptr, sz, val) \ Q_ASSERT(sz > 0); \ - ty *ptr = reinterpret_cast(alloca(sizeof(ty) * (sz))); \ + Q_ALLOCA_VAR(ty, ptr, sizeof(ty) * (sz)); \ for (ty *it = ptr, *eit = ptr + (sz); it != eit; ++it) \ *it = val; diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 40682aaa4b..0894d0c25b 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -367,7 +367,7 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat RETURN_RESULT(Encode::null()); } - uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint)); + Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint)); const int result = Scoped(scope, r->value())->match(s, offset, matchOffsets); Scoped regExpCtor(scope, scope.engine->regExpCtor()); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 3c6a24e035..1596f4b0fa 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -634,7 +634,7 @@ void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallD Q_ASSERT(regExp); } Scoped re(scope, regExp->value()); - uint* matchOffsets = (uint*)alloca(regExp->value()->captureCount() * 2 * sizeof(uint)); + Q_ALLOCA_VAR(uint, matchOffsets, regExp->value()->captureCount() * 2 * sizeof(uint)); uint result = re->match(string, /*offset*/0, matchOffsets); if (result == JSC::Yarr::offsetNoMatch) scope.result = Encode(-1); @@ -705,7 +705,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa ScopedString s(scope); if (re) { uint offset = 0; - uint* matchOffsets = (uint*)alloca(re->value()->captureCount() * 2 * sizeof(uint)); + Q_ALLOCA_VAR(uint, matchOffsets, re->value()->captureCount() * 2 * sizeof(uint)); while (true) { Scoped regexp(scope, re->value()); uint result = regexp->match(text, offset, matchOffsets); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index b9183313cd..be2772c23f 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -402,7 +402,7 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code } } - QV4::Value **scopes = static_cast(alloca(sizeof(QV4::Value *)*(2 + 2*scopeDepth))); + Q_ALLOCA_VAR(QV4::Value*, scopes, sizeof(QV4::Value *)*(2 + 2*scopeDepth)); { scopes[0] = const_cast(context->d()->compilationUnit->constants); // stack gets setup in push instruction @@ -957,8 +957,6 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code return QV4::Encode::undefined(); code = exceptionHandler; } - - } #ifdef MOTH_THREADED_INTERPRETER diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 44b612e7d2..41bb85c351 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -290,9 +290,11 @@ int QQmlValueTypeWrapper::typeId() const bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const { bool destructGadgetOnExit = false; + Q_ALLOCA_DECLARE(void, gadget); if (const QQmlValueTypeReference *ref = as()) { if (!d()->gadgetPtr) { - d()->gadgetPtr = alloca(d()->valueType->metaType.sizeOf()); + Q_ALLOCA_ASSIGN(void, gadget, d()->valueType->metaType.sizeOf()); + d()->gadgetPtr = gadget; d()->valueType->metaType.construct(d()->gadgetPtr, 0); destructGadgetOnExit = true; } diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h index 63585fd62e..026be5a703 100644 --- a/src/qml/qtqmlglobal_p.h +++ b/src/qml/qtqmlglobal_p.h @@ -55,6 +55,46 @@ #include #include +// Define Q_ALLOCA_VAR macro to be used instead of #ifdeffing +// the occurrences of alloca() in case it's not supported. +// Q_ALLOCA_DECLARE and Q_ALLOCA_ASSIGN macros separate +// memory allocation from the declaration and RAII. +#define Q_ALLOCA_VAR(type, name, size) \ + Q_ALLOCA_DECLARE(type, name); \ + Q_ALLOCA_ASSIGN(type, name, size) + +#if QT_CONFIG(alloca) + +#define Q_ALLOCA_DECLARE(type, name) \ + type *name = 0 + +#define Q_ALLOCA_ASSIGN(type, name, size) \ + name = static_cast(alloca(size)) + +#else +QT_BEGIN_NAMESPACE +class Qt_AllocaWrapper +{ +public: + Qt_AllocaWrapper() { m_data = 0; } + ~Qt_AllocaWrapper() { free(m_data); } + void *data() { return m_data; } + void allocate(int size) { m_data = malloc(size); } +private: + void *m_data; +}; +QT_END_NAMESPACE + +#define Q_ALLOCA_DECLARE(type, name) \ + Qt_AllocaWrapper _qt_alloca_##name; \ + type *name = 0 + +#define Q_ALLOCA_ASSIGN(type, name, size) \ + _qt_alloca_##name.allocate(size); \ + name = static_cast(_qt_alloca_##name.data()) + +#endif + #if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB) # define Q_QML_PRIVATE_EXPORT #else diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index cc4ccbaeb1..5e2ff9b15b 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -1268,7 +1268,7 @@ void ModelNodeMetaObject::updateValues() const int roleCount = m_model->m_listModel->roleCount(); if (!m_initialized) { if (roleCount) { - int *changedRoles = reinterpret_cast(alloca(roleCount * sizeof(int))); + Q_ALLOCA_VAR(int, changedRoles, roleCount * sizeof(int)); for (int i = 0; i < roleCount; ++i) changedRoles[i] = i; emitDirectNotifies(changedRoles, roleCount); -- cgit v1.2.3