From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by sourceware.org (Postfix) with ESMTPS id 28D853851C0E for ; Wed, 8 Jul 2020 08:48:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 28D853851C0E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wm1-x333.google.com with SMTP id 22so2042735wmg.1 for ; Wed, 08 Jul 2020 01:48:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=h8OpNFHUaDods8s9ARDrp7U35I3Dh6M6aYQZb9/tY4g=; b=cr5YgE6DC+wy6q2ConSssE8ipN5K1xslbEX9zpZ3ZJlaLaY5TZeOcpzY2hRuSQVO2U 6lXogBEHL6oEoBBWu/pqBkGGivPVGnD9nBcuuUg1Atpu5YlY+Iz8QqU2Flvw8Usji45K ZCHnOxcCW8gx2jsyAvzNC5eu9ySqHmm8gsK6Jb1MsfWvfwgbu1VyvaIxjeT2DczdSbOp yY0hs4EMDtvNhoHz8d4Opqty/H3nDG2KSx+6GCE4PIbUdnUrImH5atz1+sKnwQQSDPs7 x/ypAdk4YJoaKNLzMFWcEq3MYOBQHgmIDF3C2mws+LGxxKk5u594w2QqWH49qzZhpsoZ 8vWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=h8OpNFHUaDods8s9ARDrp7U35I3Dh6M6aYQZb9/tY4g=; b=rz8WXnp/BwMNKujLdlO+vpIjOm82+Ea3O238tld2iWHiP8k6lAOIQrhxp8Sm5Nf8jT r7Y/ePEf3jsDFTDIuIdgxR9H/VjaNvM6OYQT/x2uBqy46+4PjkaciEssOKB9ONtulYuA nVFRaWryJ62DdvNqOdKC7I5G5qeKotDYaRBV23/uJ3x43EWU3zH3vogQKO6ruUPCGtLt eJL5rEoGaOfqdyWBCYuj4fRz2IpFnZ05LVDz6wvLWvXnq9GMQhMJDsbNkPngk2fzPRsh w1d1w8ZoWUGOC4j/e5gIYc51Bw/444ErysasjSexALikpcQ9fwVP52AbvHVMcqxmLMUi 3kOQ== X-Gm-Message-State: AOAM530ajVrUJsnohxsjk/KIDYw1oXR62fcWv3SfD0U7WIjn2Le2hgFK CuY41V1OvgdELVkd6wjz8zV/X536Dyg= X-Google-Smtp-Source: ABdhPJyHeKyNmoMd4NuYMtySTwIlkOpM3KWJaVFUZfSBXKRo76rca0hBj5vFcLYliAzAjNCc7hlsJw== X-Received: by 2002:a1c:4444:: with SMTP id r65mr7860637wma.129.1594198097994; Wed, 08 Jul 2020 01:48:17 -0700 (PDT) Received: from localhost (host109-154-20-168.range109-154.btcentralplus.com. [109.154.20.168]) by smtp.gmail.com with ESMTPSA id d10sm4819317wrx.66.2020.07.08.01.48.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Jul 2020 01:48:17 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Subject: [PATCH 2/2] gdb/python: Reuse gdb.RegisterGroup objects where possible Date: Wed, 8 Jul 2020 09:48:12 +0100 Message-Id: <14e217dbd8200e3b07baf255e754bea738093d64.1594197735.git.andrew.burgess@embecosm.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jul 2020 08:48:20 -0000 Only create one gdb.RegisterGroup Python object for each of GDB's reggroup objects. I could have added a field into the reggroup object to hold the Python object pointer for each reggroup, however, as reggroups are never deleted within GDB, and are global (not per-architecture) a simpler solution seemed to be just to hold a single global map from reggroup pointer to a Python object representing the reggroup. Then we can reuse the objects out of this map. After this commit it is possible for a user to tell that two gdb.RegisterGroup objects are now identical when previously they were unique, however, as both these objects are read-only I don't think this should be a problem. There should be no other user visible changes after this commit. gdb/ChangeLog: * python/py-registers.c : Add 'unordered_map' include. (gdbpy_new_reggroup): Renamed to... (gdbpy_get_reggroup): ...this. Update to only create register group descriptors when needed. (gdbpy_reggroup_iter_next): Update. gdb/testsuite/ChangeLog: * gdb.python/py-arch-reg-groups.exp: Additional tests. --- gdb/ChangeLog | 8 ++++ gdb/python/py-registers.c | 40 ++++++++++++++----- gdb/testsuite/ChangeLog | 4 ++ .../gdb.python/py-arch-reg-groups.exp | 19 +++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c index fec84e5d5d4..5d0f5386533 100644 --- a/gdb/python/py-registers.c +++ b/gdb/python/py-registers.c @@ -23,6 +23,7 @@ #include "disasm.h" #include "reggroups.h" #include "python-internal.h" +#include /* Token to access per-gdbarch data related to register descriptors. */ static struct gdbarch_data *gdbpy_register_object_data = NULL; @@ -96,18 +97,37 @@ gdbpy_register_object_data_init (struct gdbarch *gdbarch) return (void *) vec; } -/* Create a new gdb.RegisterGroup object wrapping REGGROUP. */ +/* Return a gdb.RegisterGroup object wrapping REGGROUP. The register + group objects are cached, and the same Python object will always be + returned for the same REGGROUP pointer. */ static PyObject * -gdbpy_new_reggroup (struct reggroup *reggroup) +gdbpy_get_reggroup (struct reggroup *reggroup) { - /* Create a new object and fill in its details. */ - reggroup_object *group - = PyObject_New (reggroup_object, ®group_object_type); - if (group == NULL) - return NULL; - group->reggroup = reggroup; - return (PyObject *) group; + /* Map from GDB's internal reggroup objects to the Python representation. + GDB's reggroups are global, and are never deleted, so using a map like + this is safe. */ + static std::unordered_map + gdbpy_reggroup_object_map; + + /* If there is not already a suitable Python object in the map then + create a new one, and add it to the map. */ + if (gdbpy_reggroup_object_map[reggroup] == nullptr) + { + /* Create a new object and fill in its details. */ + reggroup_object *group + = PyObject_New (reggroup_object, ®group_object_type); + if (group == NULL) + return NULL; + group->reggroup = reggroup; + gdbpy_reggroup_object_map[reggroup] = group; + } + + /* Fetch the Python object wrapping REGGROUP from the map, increment its + reference count and return it. */ + PyObject *obj = (PyObject *) gdbpy_reggroup_object_map[reggroup]; + Py_INCREF (obj); + return obj; } /* Convert a gdb.RegisterGroup to a string, it just returns the name of @@ -219,7 +239,7 @@ gdbpy_reggroup_iter_next (PyObject *self) } iter_obj->reggroup = next_group; - return gdbpy_new_reggroup (iter_obj->reggroup); + return gdbpy_get_reggroup (iter_obj->reggroup); } /* Return a new gdb.RegisterGroupsIterator over all the register groups in diff --git a/gdb/testsuite/gdb.python/py-arch-reg-groups.exp b/gdb/testsuite/gdb.python/py-arch-reg-groups.exp index ea9aa77b0fa..093de2e7390 100644 --- a/gdb/testsuite/gdb.python/py-arch-reg-groups.exp +++ b/gdb/testsuite/gdb.python/py-arch-reg-groups.exp @@ -85,3 +85,22 @@ for { set i 0 } { $i < [llength $groups] } { incr i } { } } gdb_assert { $found_non_match == 0 } "all register groups match" + +# Check that we get the same register group descriptors from two +# different iterators. +gdb_py_test_silent_cmd \ + "python iter1 = arch.register_groups ()" \ + "get first all register group iterator" 0 +gdb_py_test_silent_cmd \ + "python iter2 = arch.register_groups ()" \ + "get second all register group iterator" 0 +gdb_py_test_silent_cmd \ + [multi_line_input \ + "python" \ + "for r1, r2 in zip(iter1, iter2):" \ + " if (r1.name != r2.name):"\ + " raise gdb.GdbError (\"miss-matched names\")" \ + " if (r1 != r2):" \ + " raise gdb.GdbError (\"miss-matched objects\")" \ + "\004" ] \ + "check names and objects match" 1 -- 2.25.4