Fix a memory management issues with the name map in internal classes
authorSimon Hausmann <simon.hausmann@digia.com>
Sun, 23 Jun 2013 11:35:17 +0000 (13:35 +0200)
committerLars Knoll <lars.knoll@digia.com>
Sun, 23 Jun 2013 19:36:08 +0000 (21:36 +0200)
The string pointer we store in the nameMap is not marked directly, i.e. our
class hierarchy doesn't have a recursive mark() function. So we must otherwise
make sure that that string is marked, otherwise we get dangling pointers that
are likely to point to _other_ strings later. This is hard to reproduce, but it
does happen with MM_AGGRESSIVE_GC=1 and the singletonType test in
qqmlecmascript, when due to the dangling pointer we end up using the wrong
property name in freeze() when iterating through the name map.

This patch fixes that by storing the actual identifier string, that's
guaranteed to get marked.

Change-Id: I28d1a2d2f56fe3abf692229ba008af8b0789189e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4internalclass.cpp

index 6fbc3d4..3232013 100644 (file)
@@ -106,7 +106,13 @@ InternalClass *InternalClass::addMember(String *string, PropertyAttributes data,
     // create a new class and add it to the tree
     InternalClass *newClass = engine->newClass(*this);
     newClass->propertyTable.insert(string->identifier, size);
-    newClass->nameMap.append(string);
+
+    // The incoming string can come from anywhere, so make sure to
+    // store a string in the nameMap that's guaranteed to get
+    // marked properly during GC.
+    String *name = engine->newIdentifier(string->toQString());
+    newClass->nameMap.append(name);
+
     newClass->propertyData.append(data);
     ++newClass->size;
     transitions.insert(id, newClass);