aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp5
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h59
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h5
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
4 files changed, 37 insertions, 34 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 1f5c22eb97..9dbebd1128 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -242,6 +242,11 @@ void InstructionSelection::run(int functionIndex)
addInstruction(set);
}
exceptionHandler = _block->catchBlock;
+ } else if (_block->catchBlock == nullptr && _block->index() != 0 && _block->in.isEmpty()) {
+ exceptionHandler = nullptr;
+ Instruction::SetExceptionHandler set;
+ set.offset = 0;
+ addInstruction(set);
}
for (IR::Stmt *s : _block->statements()) {
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 242f26ee0d..3a507bef74 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -149,40 +149,38 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef
Q_OBJECT
public:
- class BindingRefCount : public QQmlRefCount {
+ class FunctionRefCount : public QQmlRefCount {
public:
- BindingRefCount(QQmlBinding *binding):
- m_binding(binding)
+ FunctionRefCount(QV4::Function *function):
+ m_function(function)
{
- m_binding->ref.ref();
+ m_function->compilationUnit->addref();
}
- BindingRefCount(const BindingRefCount &other) :
- QQmlRefCount(other), m_binding(other.m_binding)
+ FunctionRefCount(const FunctionRefCount &other) :
+ QQmlRefCount(other), m_function(other.m_function)
{
- m_binding->ref.ref();
+ m_function->compilationUnit->addref();
}
- BindingRefCount &operator=(const BindingRefCount &other)
+ FunctionRefCount &operator=(const FunctionRefCount &other)
{
if (this != &other) {
QQmlRefCount::operator=(other);
- other.m_binding->ref.ref();
- if (!m_binding->ref.deref())
- delete m_binding;
- m_binding = other.m_binding;
+ other.m_function->compilationUnit->addref();
+ m_function->compilationUnit->release();
+ m_function = other.m_function;
}
return *this;
}
- ~BindingRefCount()
+ ~FunctionRefCount()
{
- if (!m_binding->ref.deref())
- delete m_binding;
+ m_function->compilationUnit->release();
}
private:
- QQmlBinding *m_binding;
+ QV4::Function *m_function;
};
struct Location {
@@ -199,14 +197,10 @@ public:
RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false)
{}
- RefLocation(QQmlBinding *binding, QV4::FunctionObject *function) :
+ RefLocation(QV4::Function *function) :
Location(function->sourceLocation()), locationType(Binding),
- ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
- {}
-
- RefLocation(QQmlBinding *binding, QV4::Function *function) :
- Location(function->sourceLocation()), locationType(Binding),
- ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
+ ref(new FunctionRefCount(function),
+ QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
{}
RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj,
@@ -236,16 +230,21 @@ public:
typedef QHash<quintptr, Location> LocationHash;
- void startBinding(QQmlBinding *binding, QV4::Function *function)
+ void startBinding(QV4::Function *function)
{
- quintptr locationId(id(binding));
+ // Use the QV4::Function as ID, as that is common among different instances of the same
+ // component. QQmlBinding is per instance.
+ // Add 1 to the ID, to make it different from the IDs the V4 profiler produces. The +1 makes
+ // the pointer point into the middle of the QV4::Function. Thus it still points to valid
+ // memory but we cannot accidentally create a duplicate key from another object.
+ quintptr locationId(id(function) + 1);
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), Binding,
locationId));
RefLocation &location = m_locations[locationId];
if (!location.isValid())
- location = RefLocation(binding, function);
+ location = RefLocation(function);
}
// Have toByteArrays() construct another RangeData event from the same QString later.
@@ -281,7 +280,8 @@ public:
Creating, id(obj)));
}
- void updateCreating(const QV4::CompiledData::Object *obj, QV4::CompiledData::CompilationUnit *ref,
+ void updateCreating(const QV4::CompiledData::Object *obj,
+ QV4::CompiledData::CompilationUnit *ref,
const QUrl &url, const QString &type)
{
quintptr locationId(id(obj));
@@ -330,12 +330,11 @@ struct QQmlProfilerHelper : public QQmlProfilerDefinitions {
};
struct QQmlBindingProfiler : public QQmlProfilerHelper {
- QQmlBindingProfiler(QQmlProfiler *profiler, QQmlBinding *binding,
- QV4::Function *function) :
+ QQmlBindingProfiler(QQmlProfiler *profiler, QV4::Function *function) :
QQmlProfilerHelper(profiler)
{
Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler,
- startBinding(binding, function));
+ startBinding(function));
}
~QQmlBindingProfiler()
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index d27e853343..f75ac4d33a 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -158,12 +158,11 @@ public:
FunctionCall &operator=(const FunctionCall &other) {
if (&other != this) {
- if (m_function)
- m_function->compilationUnit->release();
+ other.m_function->compilationUnit->addref();
+ m_function->compilationUnit->release();
m_function = other.m_function;
m_start = other.m_start;
m_end = other.m_end;
- m_function->compilationUnit->addref();
}
return *this;
}
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 284ae1f36f..62288a5845 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -163,7 +163,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
- QQmlBindingProfiler prof(ep->profiler, this, function());
+ QQmlBindingProfiler prof(ep->profiler, function());
doUpdate(watcher, flags, scope);
if (!watcher.wasDeleted())