From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by sourceware.org (Postfix) with ESMTPS id C82593857C6A for ; Tue, 14 Jul 2020 22:28:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C82593857C6A 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-x329.google.com with SMTP id c80so1269257wme.0 for ; Tue, 14 Jul 2020 15:28:48 -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=+Pb/y7t2o68qebgputAlqYyc/mVklX9/6nsO10NpqrU=; b=HOsHgjhb832vmQLq9X0SKsY4NubZV/Yh6HO522iz62QElUFnLRLythAOUPTil4h2fK YCu5ppxaaQcAX7fr6mEeEUNBfb0pbMsCrF/iiW3onMmFabi/6O8Sxyv5vOs0B/sg8Bg4 doCt1smfM4CpVyCW2ks8rhSp5wp+7o6Did6Lf9VigytmbTJhkvGFRhHUKPgu1TTL5Rl3 QLbBGAtRAi93FudeY8lUosU4lTqOKm/UPN8TOJtORunxcFYcCe51wJ/fC1sqccH9cp3O HzHlVgS5oTZ8RKpGhNLhMWCuvx23SBHQHqqMwYCjYGmdWlJZet2J+5c1ZrEA1X14rSkF Ulmw== 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=+Pb/y7t2o68qebgputAlqYyc/mVklX9/6nsO10NpqrU=; b=hdDfI6hiME68kzhV8RuY8TwTpw4Meu98gkwaY8yYGDnjVqJCx67DwzwghsSXoBapEd z6NDg93mJcOuBrOkyY6Z7KzLs03U5dYbSsg5akZJP6Ll+923wLJ1No3wncoBAzX8Xdx9 hTfGkQ5Wl2EUQ1YBdcDLZjUTIsoPdrlNcEgwW/DuVyw9k5J0DmWZ+8JhCf5d9G6oQQif OaYN85Vf1a3uRcVaPDvKx/GQcFQNWExJxj7cc+Oz/rp7oPYqKV6EdVUrjNpd+U6OebQm c3GncR7lHGhJoIo79+ss/M2IRma3PDfoDjRh4LOgjNCVnsUk5JT5adWrnP3bpj+YXvIu hBiw== X-Gm-Message-State: AOAM531raLlcnRkTGNlQSRe5JAvuPhFnSvTHkyoI6PsWQXvRynMgfo8G GO7ddJk+TKd/ubxP5eorm+1f2Vs4mr0= X-Google-Smtp-Source: ABdhPJylfIaqACZts0tNc5SYFCmmRhd8zhjm4sX6wjChhJB852KUuMq1MB6Lr0fiz2dglCo1hF3R6g== X-Received: by 2002:a7b:c857:: with SMTP id c23mr5156160wml.155.1594746878342; Tue, 14 Jul 2020 10:14:38 -0700 (PDT) Received: from localhost (host86-128-12-23.range86-128.btcentralplus.com. [86.128.12.23]) by smtp.gmail.com with ESMTPSA id v15sm5104608wmh.24.2020.07.14.10.14.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Jul 2020 10:14:37 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Tom Tromey , Andrew Burgess Subject: [PATCHv2 2/2] gdb/python: Reuse gdb.RegisterGroup objects where possible Date: Tue, 14 Jul 2020 18:14:31 +0100 Message-Id: <79248e49ee64410e7f7a943914b2b07084c433d7.1594746770.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.1 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: Tue, 14 Jul 2020 22:28:50 -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 | 41 ++++++++++++++----- gdb/testsuite/ChangeLog | 4 ++ .../gdb.python/py-arch-reg-groups.exp | 19 +++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/gdb/python/py-registers.c b/gdb/python/py-registers.c index 8e22a919d87..9396498cc34 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; @@ -95,18 +96,36 @@ 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) +static gdbpy_ref<> +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. */ + gdbpy_ref group + (PyObject_New (reggroup_object, ®group_object_type)); + if (group == NULL) + return NULL; + group->reggroup = reggroup; + gdbpy_reggroup_object_map[reggroup] + = gdbpy_ref<> ((PyObject *) group.release ()); + } + + /* Fetch the Python object wrapping REGGROUP from the map, increasing + the reference count is handled by the gdbpy_ref class. */ + return gdbpy_reggroup_object_map[reggroup]; } /* Convert a gdb.RegisterGroup to a string, it just returns the name of @@ -215,7 +234,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).release (); } /* 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