Fix crashes with unmarked runtime strings
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 15 Aug 2013 12:11:19 +0000 (14:11 +0200)
committerLars Knoll <lars.knoll@digia.com>
Thu, 15 Aug 2013 13:28:46 +0000 (15:28 +0200)
Runtime strings are identifiers, but they still require to be marked. Keep
track of all compilation units in the engine (one per file) and mark its
run-time strings.

Change-Id: Ie70b00dfa373c4567279591de2f717e8103c288f
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/compiler/qv4compileddata.cpp
src/qml/compiler/qv4compileddata_p.h
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h

index c4d7509..38461af 100644 (file)
@@ -56,6 +56,7 @@ int Function::calculateSize(QQmlJS::V4IR::Function *f)
 
 CompilationUnit::~CompilationUnit()
 {
+    engine->compilationUnits.erase(engine->compilationUnits.find(this));
     free(data);
     free(runtimeStrings);
     delete [] runtimeLookups;
@@ -63,6 +64,9 @@ CompilationUnit::~CompilationUnit()
 
 QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
 {
+    this->engine = engine;
+    engine->compilationUnits.insert(this);
+
     assert(!runtimeStrings);
     assert(data);
     runtimeStrings = (QV4::String**)malloc(data->stringTableSize * sizeof(QV4::String*));
@@ -93,6 +97,12 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
     return linkBackendToEngine(engine);
 }
 
+void CompilationUnit::markObjects()
+{
+    for (int i = 0; i < data->stringTableSize; ++i)
+        runtimeStrings[i]->mark();
+}
+
 }
 
 }
index de5c82b..cd8a76b 100644 (file)
@@ -256,6 +256,7 @@ struct CompilationUnit
 {
     CompilationUnit()
         : refCount(0)
+        , engine(0)
         , data(0)
         , runtimeStrings(0)
         , runtimeLookups(0)
@@ -266,6 +267,7 @@ struct CompilationUnit
     void deref() { if (!--refCount) delete this; }
 
     int refCount;
+    ExecutionEngine *engine;
     Unit *data;
 
     QString fileName() const { return data->stringAt(data->sourceFileIndex)->qString(); }
@@ -280,6 +282,8 @@ struct CompilationUnit
     // ### runtime data
     // pointer to qml data for QML unit
 
+    void markObjects();
+
 protected:
     virtual QV4::Function *linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
 };
index f346321..764f3fa 100644 (file)
@@ -789,6 +789,10 @@ void ExecutionEngine::markObjects()
 
     if (m_qmlExtensions)
         m_qmlExtensions->markObjects();
+
+    for (QSet<CompiledData::CompilationUnit*>::ConstIterator it = compilationUnits.constBegin(), end = compilationUnits.constEnd();
+         it != end; ++it)
+        (*it)->markObjects();
 }
 
 namespace {
index a6bf2ef..6a7442d 100644 (file)
@@ -60,6 +60,9 @@ namespace QV4 {
 namespace Debugging {
 class Debugger;
 } // namespace Debugging
+namespace CompiledData {
+struct CompilationUnit;
+}
 }
 
 namespace QV4 {
@@ -201,6 +204,8 @@ struct Q_QML_EXPORT ExecutionEngine
     mutable QVector<Function *> functions;
     mutable bool functionsNeedSort;
 
+    QSet<CompiledData::CompilationUnit*> compilationUnits;
+
     quint32 m_engineId;
 
     RegExpCache *regExpCache;