From 6d6c8e468fe459a412adb8f6acdd9d889e056a2d Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Thu, 10 Jun 2010 15:11:12 +0200
Subject: [PATCH] debugger: cache results of gdb.lookup_type

---
 share/qtcreator/gdbmacros/dumper.py    | 30 ++++++++++------
 share/qtcreator/gdbmacros/gdbmacros.py | 48 +++++++++++++-------------
 2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index 6ff13421fd9..e54b63f8bfa 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -88,12 +88,22 @@ def isGoodGdb():
     #   and gdb.VERSION != "6.8.50.20090630-cvs"
     return 'parse_and_eval' in __builtin__.dir(gdb)
 
+typeCache = {}
+
+def lookupType(typestring):
+    type = typeCache.get(typestring)
+    #warn("LOOKUP: %s -> %s" % (typestring, type))
+    if type is None:
+        type = gdb.lookup_type(typestring)
+        typeCache[typestring] = type
+    return type
+
 def cleanAddress(addr):
     if addr is None:
         return "<no address>"
     # We cannot use str(addr) as it yields rubbish for char pointers
     # that might trigger Unicode encoding errors.
-    return addr.cast(gdb.lookup_type("void").pointer())
+    return addr.cast(lookupType("void").pointer())
 
 # Workaround for gdb < 7.1
 def numericTemplateArgument(type, position):
@@ -535,7 +545,7 @@ def checkRef(ref):
     check(count < 1000000) # assume there aren't a million references to any object
 
 #def couldBePointer(p, align):
-#    type = gdb.lookup_type("unsigned int")
+#    type = lookupType("unsigned int")
 #    ptr = gdb.Value(p).cast(type)
 #    d = int(str(ptr))
 #    warn("CHECKING : %s %d " % (p, ((d & 3) == 0 and (d > 1000 or d == 0))))
@@ -559,7 +569,7 @@ def isNull(p):
     # for invalid char *, as their "contents" is being examined
     #s = str(p)
     #return s == "0x0" or s.startswith("0x0 ")
-    return p.cast(gdb.lookup_type("void").pointer()) == 0
+    return p.cast(lookupType("void").pointer()) == 0
 
 movableTypes = set([
     "QBrush", "QBitArray", "QByteArray",
@@ -648,7 +658,7 @@ def findFirstZero(p, max):
 
 
 def extractCharArray(p, maxsize):
-    t = gdb.lookup_type("unsigned char").pointer()
+    t = lookupType("unsigned char").pointer()
     p = p.cast(t)
     i = findFirstZero(p, maxsize)
     limit = select(i < 0, maxsize, i)
@@ -673,7 +683,7 @@ def extractByteArray(value):
     return extractCharArray(data, 100)
 
 def encodeCharArray(p, maxsize, size = -1):
-    t = gdb.lookup_type("unsigned char").pointer()
+    t = lookupType("unsigned char").pointer()
     p = p.cast(t)
     if size == -1:
         i = findFirstZero(p, maxsize)
@@ -689,7 +699,7 @@ def encodeCharArray(p, maxsize, size = -1):
     return s
 
 def encodeChar2Array(p, maxsize):
-    t = gdb.lookup_type("unsigned short").pointer()
+    t = lookupType("unsigned short").pointer()
     p = p.cast(t)
     i = findFirstZero(p, maxsize)
     limit = select(i < 0, maxsize, i)
@@ -702,7 +712,7 @@ def encodeChar2Array(p, maxsize):
     return s
 
 def encodeChar4Array(p, maxsize):
-    t = gdb.lookup_type("unsigned int").pointer()
+    t = lookupType("unsigned int").pointer()
     p = p.cast(t)
     i = findFirstZero(p, maxsize)
     limit = select(i < 0, maxsize, i)
@@ -774,7 +784,7 @@ class FrameCommand(gdb.Command):
         super(FrameCommand, self).__init__("bb", gdb.COMMAND_OBSCURE)
 
     def invoke(self, args, from_tty):
-        if True:
+        if False:
             bb(args)
         else:
             import cProfile
@@ -1097,7 +1107,7 @@ class Dumper:
     def putPointerValue(self, value):
         # Use a lower priority
         self.putValue("0x%x" % value.dereference().cast(
-            gdb.lookup_type("unsigned long")), None, -1)
+            lookupType("unsigned long")), None, -1)
 
     def putStringValue(self, value):
         if value is None:
@@ -1381,7 +1391,7 @@ class Dumper:
             if self.isExpanded(item):
                 if value.type.code == gdb.TYPE_CODE_ARRAY:
                     baseptr = value.cast(value.type.target().pointer())
-                    charptr = gdb.lookup_type("unsigned char").pointer()
+                    charptr = lookupType("unsigned char").pointer()
                     addr1 = (baseptr+1).cast(charptr)
                     addr0 = baseptr.cast(charptr)
                     self.putField("addrbase", cleanAddress(addr0))
diff --git a/share/qtcreator/gdbmacros/gdbmacros.py b/share/qtcreator/gdbmacros/gdbmacros.py
index e27abf5c5df..8296d8e4da9 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.py
+++ b/share/qtcreator/gdbmacros/gdbmacros.py
@@ -27,7 +27,7 @@ def qdump__QByteArray(d, item):
     d.putNumChild(size)
 
     if d.isExpanded(item):
-        innerType = gdb.lookup_type("char")
+        innerType = lookupType("char")
         with Children(d, [size, 1000], innerType):
             data = d_ptr['data']
             p = gdb.Value(data.cast(innerType.pointer()))
@@ -57,7 +57,7 @@ def qdump__QAbstractItem(d, item):
     d.putNumChild(rowCount * columnCount)
     if d.isExpanded(item):
         with Children(d):
-            innerType = gdb.lookup_type(d.ns + "QAbstractItem")
+            innerType = lookupType(d.ns + "QAbstractItem")
             for row in xrange(rowCount):
                 for column in xrange(columnCount):
                     with SubItem(d):
@@ -202,7 +202,7 @@ def qdump__QFileInfo(d, item):
     d.putStringValue(call(item.value, "filePath()"))
     d.putNumChild(3)
     if d.isExpanded(item):
-        with Children(d, 10, gdb.lookup_type(d.ns + "QString")):
+        with Children(d, 10, lookupType(d.ns + "QString")):
             d.putCallItem("absolutePath", item, "absolutePath()")
             d.putCallItem("absoluteFilePath", item, "absoluteFilePath()")
             d.putCallItem("canonicalPath", item, "canonicalPath()")
@@ -406,7 +406,7 @@ def qdump__QList(d, item):
         # in the frontend.
         # So as first approximation only do the 'isLarge' check:
         isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
-        dummyType = gdb.lookup_type("void").pointer().pointer()
+        dummyType = lookupType("void").pointer().pointer()
         innerTypePointer = innerType.pointer()
         p = gdb.Value(array).cast(dummyType) + begin
         if innerTypeIsPointer:
@@ -458,7 +458,7 @@ def qdump__QImage(d, item):
             d.put("%08x" % int(d_ptr["width"]))
             d.put("%08x" % int(d_ptr["height"]))
             d.put("%08x" % int(d_ptr["format"]))
-            p = bits.cast(gdb.lookup_type("unsigned int").pointer())
+            p = bits.cast(lookupType("unsigned int").pointer())
             for i in xrange(nbytes / 4):
                 d.put("%08x" % int(p.dereference()))
                 p += 1
@@ -467,7 +467,7 @@ def qdump__QImage(d, item):
             # Write to an external file. Much faster ;-(
             file = tempfile.mkstemp(prefix="gdbpy_")
             filename = file[1].replace("\\", "\\\\")
-            p = bits.cast(gdb.lookup_type("unsigned char").pointer())
+            p = bits.cast(lookupType("unsigned char").pointer())
             gdb.execute("dump binary memory %s %s %s" %
                 (filename, cleanAddress(p), cleanAddress(p + nbytes)))
             d.putDisplay(DisplayImage, " %d %d %d %s"
@@ -494,7 +494,7 @@ def qdump__QLocale(d, item):
     d.putStringValue(call(item.value, "name()"))
     d.putNumChild(8)
     if d.isExpanded(item):
-        with Children(d, 1, gdb.lookup_type(d.ns + "QChar"), 0):
+        with Children(d, 1, lookupType(d.ns + "QChar"), 0):
             d.putCallItem("country", item, "country()")
             d.putCallItem("language", item, "language()")
             d.putCallItem("measurementSystem", item, "measurementSystem()")
@@ -548,9 +548,9 @@ def qdump__QMap(d, item):
         # QMapPayloadNode is QMapNode except for the 'forward' member, so
         # its size is most likely the offset of the 'forward' member therein.
         # Or possibly 2 * sizeof(void *)
-        nodeType = gdb.lookup_type(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
-        payloadSize = nodeType.sizeof - 2 * gdb.lookup_type("void").pointer().sizeof
-        charPtr = gdb.lookup_type("char").pointer()
+        nodeType = lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
+        payloadSize = nodeType.sizeof - 2 * lookupType("void").pointer().sizeof
+        charPtr = lookupType("char").pointer()
 
         innerType = select(isSimpleKey and isSimpleValue, valueType, nodeType)
 
@@ -601,7 +601,7 @@ def qdump__QObject(d, item):
     #    superData = superData.dereference()["d"]["superdata"]
     #    warn("SUPERDATA: %s" % superData)
 
-    privateType = gdb.lookup_type(d.ns + "QObjectPrivate").pointer()
+    privateType = lookupType(d.ns + "QObjectPrivate").pointer()
     d_ptr = item.value["d_ptr"]["d"].cast(privateType).dereference()
     #warn("D_PTR: %s " % d_ptr)
     objectName = d_ptr["objectName"]
@@ -638,7 +638,7 @@ def qdump__QObject(d, item):
             if isNull(extraData):
                 dynamicPropertyCount = 0
             else:
-                extraDataType = gdb.lookup_type(
+                extraDataType = lookupType(
                     d.ns + "QObjectPrivate::ExtraData").pointer()
                 extraData = extraData.cast(extraDataType)
                 ed = extraData.dereference()
@@ -664,12 +664,12 @@ def qdump__QObject(d, item):
             if d.isExpandedIName(item.iname + ".properties"):
                 with Children(d, [propertyCount, 500]):
                     # Dynamic properties.
-                    dummyType = gdb.lookup_type("void").pointer().pointer()
-                    namesType = gdb.lookup_type(d.ns + "QByteArray")
+                    dummyType = lookupType("void").pointer().pointer()
+                    namesType = lookupType(d.ns + "QByteArray")
                     valuesBegin = values["d"]["begin"]
                     valuesEnd = values["d"]["end"]
                     valuesArray = values["d"]["array"]
-                    valuesType = gdb.lookup_type(d.ns + "QVariant")
+                    valuesType = lookupType(d.ns + "QVariant")
                     p = namesArray.cast(dummyType) + namesBegin
                     q = valuesArray.cast(dummyType) + valuesBegin
                     for i in xrange(dynamicPropertyCount):
@@ -720,7 +720,7 @@ def qdump__QObject(d, item):
                            #    type = type[type.find('"') + 1 : type.rfind('"')]
                            #    type = type.replace("Q", d.ns + "Q") # HACK!
                            #    data = call(item.value, "constData()")
-                           #    tdata = data.cast(gdb.lookup_type(type).pointer()).dereference()
+                           #    tdata = data.cast(lookupType(type).pointer()).dereference()
                            #    d.putValue("(%s)" % tdata.type)
                            #    d.putType(tdata.type)
                            #    d.putNumChild(1)
@@ -1485,7 +1485,7 @@ def qdump__QStringList(d, item):
     d.putItemCount(size)
     d.putNumChild(size)
     if d.isExpanded(item):
-        innerType = gdb.lookup_type(d.ns + "QString")
+        innerType = lookupType(d.ns + "QString")
         ptr = gdb.Value(d_ptr["array"]).cast(innerType.pointer())
         ptr += d_ptr["begin"]
         with Children(d, [size, 1000], innerType):
@@ -1645,11 +1645,11 @@ def qdumpHelper__QVariant(d, value):
         inner = d.ns + "QQuadernion"
 
     if len(inner):
-        innerType = gdb.lookup_type(inner)
-        sizePD = gdb.lookup_type(d.ns + 'QVariant::Private::Data').sizeof
+        innerType = lookupType(inner)
+        sizePD = lookupType(d.ns + 'QVariant::Private::Data').sizeof
         if innerType.sizeof > sizePD:
-            sizePS = gdb.lookup_type(d.ns + 'QVariant::PrivateShared').sizeof
-            val = (sizePS + data.cast(gdb.lookup_type('char').pointer())) \
+            sizePS = lookupType(d.ns + 'QVariant::PrivateShared').sizeof
+            val = (sizePS + data.cast(lookupType('char').pointer())) \
                 .cast(innerType.pointer()).dereference()
         else:
             val = data.cast(innerType)
@@ -1665,7 +1665,7 @@ def qdump__QVariant(d, item):
     #warn("VARIANT DATA: '%s' '%s' '%s': " % (val, inner, innert))
 
     if len(inner): 
-        innerType = gdb.lookup_type(inner)
+        innerType = lookupType(inner)
         # FIXME: Why "shared"?
         if innerType.sizeof > item.value["d"]["data"].type.sizeof:
             v = item.value["d"]["data"]["shared"]["ptr"] \
@@ -1683,7 +1683,7 @@ def qdump__QVariant(d, item):
         type = type[type.find('"') + 1 : type.rfind('"')]
         type = type.replace("Q", d.ns + "Q") # HACK!
         data = call(item.value, "constData()")
-        tdata = data.cast(gdb.lookup_type(type).pointer()).dereference()
+        tdata = data.cast(lookupType(type).pointer()).dereference()
         d.putType("%sQVariant (%s)" % (d.ns, tdata.type))
         d.putNumChild(1)
         if d.isExpanded(item):
@@ -1879,7 +1879,7 @@ def qdump__std__string(d, item):
     data = item.value["_M_dataplus"]["_M_p"]
     baseType = item.value.type.unqualified().strip_typedefs()
     charType = baseType.template_argument(0)
-    repType = gdb.lookup_type("%s::_Rep" % baseType).pointer()
+    repType = lookupType("%s::_Rep" % baseType).pointer()
     rep = (data.cast(repType) - 1).dereference()
     size = rep['_M_length']
     alloc = rep['_M_capacity']
-- 
GitLab