From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id IAX2G4Bkl2daIRwAWB0awg (envelope-from ) for ; Mon, 27 Jan 2025 05:48:32 -0500 Received: by simark.ca (Postfix, from userid 112) id 6F73D1E105; Mon, 27 Jan 2025 05:48:32 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.0 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id D8B5E1E08E for ; Mon, 27 Jan 2025 05:48:31 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 704FF3858433 for ; Mon, 27 Jan 2025 10:48:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 704FF3858433 Received: from us-smtp-delivery-114.mimecast.com (us-smtp-delivery-114.mimecast.com [170.10.133.114]) by sourceware.org (Postfix) with ESMTP id C22F6385800F for ; Mon, 27 Jan 2025 10:45:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C22F6385800F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=labware.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=labware.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C22F6385800F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.114 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1737974759; cv=none; b=gBExfHljbWzKIN3G0LZh9oM0IBP4ehU9w7y6OSQlf46a9Tpc5BiINsIuy9VNKwPam/9DJolY6F9exFC2IePdxMY/OE4mh9YH+Z4Ej0XHn3f5oylXMlZwgewWMQB69/EO8Hahm9+g5nEiy89jg7XlqDqeBYugDjiUVf1lEphdFbk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1737974759; c=relaxed/simple; bh=6A3o0ERhCfkUjoXPvzE/9bAwRiHlSu3I+E6kvi5oe90=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=H2iOwSzGxMFdHNrnmTyvvcWJJg0wFHLd3AHbqv+Zq0WBEDH2L2XfuULuKJVBrcOLNUcAat2K3oy9hnKZyoEXNfywKjiLso3oZqz1oNgfNhEms3vsuMt9xvGtZYdomywuAmLjlIHGxNfWWravhxh7X50Qn4zhdGYPATD/2401BOc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C22F6385800F Received: from NAM12-MW2-obe.outbound.protection.outlook.com (mail-mw2nam12lp2045.outbound.protection.outlook.com [104.47.66.45]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-202-Fluu456ZOf2sZlJYC3PWUw-1; Mon, 27 Jan 2025 05:45:58 -0500 X-MC-Unique: Fluu456ZOf2sZlJYC3PWUw-1 X-Mimecast-MFC-AGG-ID: Fluu456ZOf2sZlJYC3PWUw Received: from SA0PR17MB4314.namprd17.prod.outlook.com (2603:10b6:806:e7::16) by DM4PR17MB6954.namprd17.prod.outlook.com (2603:10b6:8:18e::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8377.22; Mon, 27 Jan 2025 10:45:56 +0000 Received: from SA0PR17MB4314.namprd17.prod.outlook.com ([fe80::38a7:a6f2:3b95:bc26]) by SA0PR17MB4314.namprd17.prod.outlook.com ([fe80::38a7:a6f2:3b95:bc26%5]) with mapi id 15.20.8377.021; Mon, 27 Jan 2025 10:45:56 +0000 From: Jan Vrany To: gdb-patches@sourceware.org CC: Jan Vrany Subject: [RFC 5/9] gdb/python: introduce gdbpy_registry Date: Mon, 27 Jan 2025 10:44:31 +0000 Message-ID: <20250127104435.823519-6-jan.vrany@labware.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250127104435.823519-1-jan.vrany@labware.com> References: <20250127104435.823519-1-jan.vrany@labware.com> X-ClientProxiedBy: LNXP265CA0031.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::19) To SA0PR17MB4314.namprd17.prod.outlook.com (2603:10b6:806:e7::16) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SA0PR17MB4314:EE_|DM4PR17MB6954:EE_ X-MS-Office365-Filtering-Correlation-Id: ee05ba26-4b29-4f34-acea-08dd3ebfc775 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024 X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?7hyD7x3PapudUYQLNPOfWID3PaxBJr0CNoN3YHlbXyDtsgARqmILf8BNa7iU?= =?us-ascii?Q?d5BG9yyg1iAxG6RfK6dAEalMh6JGQjBKf7t0Hc+scRVNm3SfoFPEe5YbL4bn?= =?us-ascii?Q?49kJ0nkGMAanjk7pJetXpjKjyYxdVMkcx2joUeieZPDb6cR2IEa6OOCajC8J?= =?us-ascii?Q?CyljBOl2RiEMJzPHjIjw0cZAkJQAR7GKpw7Ie7Q63BVNeifI+ptV/aWAFB8R?= =?us-ascii?Q?muCJ5l0MkQxJrnCgRUwx+qcKopirrgACNqyd94eqOrfp5VZywG+iNuLb3HIt?= =?us-ascii?Q?GDyBccDtF0YLgM2Uz74rNPgHDoAi7RLV35dCDfn0JAhw2qDOng6XNytIOVE/?= =?us-ascii?Q?FEonkqJugJ3W85yqIG4pJhQ5d0Oi+HsPsMuSCExXICDWmYy6D4vfM+mtJBNr?= =?us-ascii?Q?GOCgRVEMpnVGbm65rbNI2m2VPYqWCEM71FXrKzoVRF8ZXqNtxrhfIvcY1QU0?= =?us-ascii?Q?Xv1Ii49hqojMdnXw+MMWv7SlaWKLuI+j0kMJNnxVwTnJ7hbrkBgPo6c3nboD?= =?us-ascii?Q?7D49lv86SuliyhjfwJZQaDFOqEDhTVij1ZvtYjiPsI1VgjSijV2cUpKglMCd?= =?us-ascii?Q?XJ7LSTm0vuDcSXQvQ8kt214tXrqkX1e2LKOg98FRTKccGzlXmUc2P1qPDjyJ?= =?us-ascii?Q?GvwC8uvSmOfbTu0icx35yErULB8g0KZ0Pi0I3bgr69ba8o9DAf9Ue7ctwtyq?= =?us-ascii?Q?XB2rpZfnxsTm9aXoN/IMObeHvFhlHGLYJWW+zJIkTv3IrMXw4I6UWywYuryM?= =?us-ascii?Q?tk8VquX29nMKBB4MBxCkrWBya7fUzhaYtRZUdU3oZHmPjG3W0tsVG7fqtwzR?= =?us-ascii?Q?wDpjS7D3hqCTdBDUXfJqMdmSprwV4lRSI7mkU5m/VHPz/UszbFMDL/mVgtvc?= =?us-ascii?Q?6dqtoltxfvolL1f8TaaLcZhAgbveYcfa7AcOkIee9/XRxtXSnrMsIPi79sJ6?= =?us-ascii?Q?1SA7OAGZj0UN0NgdcpDUadiYeQ1sD35fZPp12P+0Z4kBpqN9NN4FwGirVxAF?= =?us-ascii?Q?EajbbqyTIZ9BGqPfarWj+4SJJW2nbsVKdxusjE0uEmgHRGN8mML64fwWzhWY?= =?us-ascii?Q?s35GpJDk2hQ2D8nxzE+7h39bn9M1V/ytlVSjCMABBqM/5JrCy4GsYNz/SbeQ?= =?us-ascii?Q?VTVYBVZpwpk9JcvQA2LseJorC3VPWZe3UGD6O+klD5HkQS0iCfdoXI82yI4L?= =?us-ascii?Q?PdjJWG0ir55OaRBqY9sSqTHIgG03DbWUSSf5BdtFfkQYQkEj1g8LR4OLXNaj?= =?us-ascii?Q?J17IjM6NIqqmOn/1Cbf1rughJF41/ODAhRAXFVU7hl9nwVJv26KKcPTlhZMy?= =?us-ascii?Q?/MvfJH9QJvdR0tIxaSMo09AXVK3i/NXtMvabDCOc6gvHtt9p7A/aBxjwQN4j?= =?us-ascii?Q?ks7wD8ozkMuIJtcw1+XcPdtn2ND7?= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:SA0PR17MB4314.namprd17.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(376014)(366016)(1800799024); DIR:OUT; SFP:1102 X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Al8AJ5+A3H0o7/qFL3KAPUB8kE/1HCo+KFooFQp5owhltWJiZEAEgo3gBcPK?= =?us-ascii?Q?wOTtY0vGZE8MZMi/R7hS3WDhaEADMOBWfmGORp4K0njlFWZWGZZMqja0ejp8?= =?us-ascii?Q?Pb567P7ShPs7/aeqWnyv99AgGg+wRn5UUg/ybQoCgUpTUQN06hjerR4vWTjw?= =?us-ascii?Q?w6d9edr0bAFoK+rRJOFoTQzAKlJpdAydp8gybRpNge3PzrYAYqgZWsEfovN4?= =?us-ascii?Q?IxEwJTunyXjTO+/qlG5BEcQLylaRAC8u+cv/R+9HqMR2wdFd6wE0FIzPWAaA?= =?us-ascii?Q?2pnTeYj3Aqsp7IKPhMxs7eQl8d5N2nBfbxRk0576VAKIhMsxMOroThJNAWnG?= =?us-ascii?Q?JmhMGvN4hPC7ivnBTh5h1WpvIHyyzgZUSNjMU7buNBxH+UIsI5F+3aHo33cY?= =?us-ascii?Q?DbOJxnvhe6ROfvu2BnsgI/FI2MFYe1P2Yxwe9jB5BjHK/y9iQvFVdOhxYxnI?= =?us-ascii?Q?Jr9sZQxrYtOontmbddv40cd78dzN+/ExaDxNIuOkKscKmWrCB99DkFg5Xayg?= =?us-ascii?Q?n1TwFxEtkq0ONhVdwA+ZMaAvu/cvOtf5EQGj0h4AMH8l3E4ujpgZjtWS2J37?= =?us-ascii?Q?fSmqs2zWpR/O/Db0AZBQvRImTkAP84mhvUSo+HeQIVhDNBNWgLwjWD8HtBOP?= =?us-ascii?Q?DSs0bXXLIvjvn/KKEYSw3P6OZFWynjc3oLW32lasYbdoSMXpPepxOv/RS2W9?= =?us-ascii?Q?qHWc4SY0BV6ZEQPWmX93s81BuOZOnF0VUhPQaFZNV4Z8bxwYMIlAaR15hJV1?= =?us-ascii?Q?y8jDg95t45eGD64unk1q1hbNmZnpUize04qBKPeSc6YFf2c69BUIlDYjIIkO?= =?us-ascii?Q?+KsEwXXZpqiNDc6diQxOqnYPzCnvbQOfjg75cjCqosycCtyCO6Ujpc63sRcs?= =?us-ascii?Q?YzVkM/KNDlyBrAEMWdU1E0v+VilizIKPzOozC9TmJjpI78LRSzPSM1BJGeyj?= =?us-ascii?Q?mUyOw1/pHKL8mVpyVgwReFL/VtdfbJkY6eZbgmhiyX+DoDx8535ks6TISS1p?= =?us-ascii?Q?a73Ndz7HKjZibcN0EaOQXrNNYzJRECH4i3c7l9yemvVlyPUnxLoCGOKHudzY?= =?us-ascii?Q?cw6un/HiHHTiZ6SyGZeBMut7V3ap0XLaQVQ1pbFB9bDQk2kVkXPYIebphMjt?= =?us-ascii?Q?psmD9Uzg83bX2Q14h0miJ0Wa5cB26HLWX0lTrWI3v+wPXXNXhsGdYjtCN324?= =?us-ascii?Q?6irOiHCbg3n/FZuCA6dQY7z4A7ZcWtckXC4MPs+vEHs7qlQgLDq0fjgvvBQM?= =?us-ascii?Q?hYTN1x+OuikdWttzsbSt0m9tgpvCcw/qEYiA6K177xLWPIhojeo63ZVnxelN?= =?us-ascii?Q?soXp/B6YrtoLddHoOsa8//Zpk5Aw4/M8i2HbguUuHcijWR3TI71qdQg/GT8G?= =?us-ascii?Q?+IjCzA54JF9SV7PgyzzmTS7rox13MeYjnMMVrlg2MVoITnFQzBbN8OoOuWYG?= =?us-ascii?Q?2zEoPFS/zhaDse0blfgXUpHlij1kS/bcLkZ4iAZFE+0oO2C8K54oXXoXNIKe?= =?us-ascii?Q?6Begp9WDnXawsorf1Y9qvi8nCpa4/Pe3MrtWA3TV9D3QT5W5Z+hoKbBBxdSo?= =?us-ascii?Q?Jizx6t9y0F5TAag55sPfVKLR7DNcjIvXkm/KZWnJ?= X-OriginatorOrg: labware.com X-MS-Exchange-CrossTenant-Network-Message-Id: ee05ba26-4b29-4f34-acea-08dd3ebfc775 X-MS-Exchange-CrossTenant-AuthSource: SA0PR17MB4314.namprd17.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Jan 2025 10:45:56.4502 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b5db0322-1aa0-4c0a-859c-ad0f96966f4c X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: Q8jHQcs85R4d3ur6sXtzOSaK60y5X0ujadlMHBB7v4Rd9N0KhdvmY1yXjhWwiZNJaYZoxoYJ+Tai5Y551uma2g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR17MB6954 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: vhOSo2gnUxyrnGQk8vy7v02McsezUixvPXqpymsvp5s_1737974757 X-Mimecast-Originator: labware.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=WINDOWS-1252 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This commit introduces new template class gdbpy_registry to simplify Python object lifecycle management. As of now, each of the Python object implementations contain its own (copy of) lifecycle management code that is largely very similar. The aim of gdbpy_registry is to factor out this code into a common (template) class in order to simplify the code. --- gdb/python/python-internal.h | 200 +++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index c48f260c15f..73df7f34a18 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -22,6 +22,10 @@ =20 #include "extension.h" #include "extension-priv.h" +#include "registry.h" +#include +#include + =20 /* These WITH_* macros are defined by the CPython API checker that comes with the Python plugin for GCC. See: @@ -1145,4 +1149,200 @@ gdbpy_type_ready (PyTypeObject *type, PyObject *mod= =3D nullptr) # define PyType_Ready POISONED_PyType_Ready #endif =20 +/* A class to manage lifecycle of Python objects for objects that are "own= ed"=20 + by an objfile or a gdbarch. It keeps track of Python objects and when + the "owning" object (objfile or gdbarch) is about to be freed, ensures = that + all Python objects "owned" by that object are properly invalidated. + + The actuall tracking of "owned" Python objects is handled externally + by storage class. Storage object is created for each owning object + on demand and it is deleted when owning object is about to be freed. + + The storage class must provide two member types: + =20 + * obj_type - the type of Python object whose lifecycle is managed.=20 + * val_type - the type of GDB structure the Python objects are=20 + representing. + + It must also provide following methods. + + void add (obj_type *obj); + void remove (obj_type *obj); + obj_type *lookup (val_type *val); + + Finally it must invalidate all registered Python objects upon deletion.= */ +template +class gdbpy_registry +{ +public: + using obj_type =3D typename Storage::obj_type; + using val_type =3D typename Storage::val_type; + + /* Register Python object OBJ as being "owned" by OWNER. When OWNER is + about to be freed, OBJ will be invalidated. */ + template + void add (O *owner, obj_type *obj) const + { + get_storage (owner)->add (obj); + } + + /* Unregister Python object OBJ. OBJ will no longer be invalidated when + OWNER is about to be be freed. */ + template + void remove (O *owner, obj_type *obj) const + { + get_storage (owner)->remove (obj); + } + + /* Lookup pre-existing Python object for given VAL. Return such object + if found, otherwise return NULL. This method always returns new + reference. */ + template + obj_type *lookup (O *owner, val_type *val) const + { + obj_type *obj =3D get_storage (owner)->lookup (val); + Py_XINCREF (obj); + return obj; + } + +private: + + template + using StorageKey =3D typename registry::key; + + template + Storage *get_storage (O *owner, const StorageKey &key) const + { + Storage *r =3D key.get (owner); + if (r =3D=3D nullptr) + { +=09r =3D new Storage(); +=09key.set (owner, r); + } + return r; + } + + Storage *get_storage(struct objfile* objf) const + { + return get_storage(objf, m_key_for_objf); + } + + Storage *get_storage(struct gdbarch* arch) const + { + return get_storage(arch, m_key_for_arch); + } + + const registry::key m_key_for_objf; + const registry::key m_key_for_arch; +}; + +/* Default invalidator for Python objects. */ +template +struct gdbpy_default_invalidator +{ + void operator() (P *obj) + { + obj->*val_slot =3D nullptr; + } +}; + +/* A "storage" implementation suitable for temporary (on-demand) objects. = */ +template > +class gdbpy_tracking_registry_storage +{ +public: + using obj_type =3D P; + using val_type =3D V; + + void add (obj_type *obj) + { + gdb_assert (obj !=3D nullptr && obj->*val_slot !=3D nullptr); + + m_objects.insert (obj); =20 + } + + void remove (obj_type *obj) + { + gdb_assert (obj !=3D nullptr && obj->*val_slot !=3D nullptr); + + m_objects.erase (obj); =20 + } + + obj_type *lookup (val_type *val) const + { + gdb_assert_not_reached ("Should not be used."); + } + + ~gdbpy_tracking_registry_storage () + { + Invalidator invalidate; + gdbpy_enter enter_py; + + for (auto each : m_objects) + invalidate (each); + m_objects.clear (); + } + +private: + std::unordered_set m_objects; +}; + +/* A "storage" implementation suitable for memoized (interned) Python obje= cts. + + This implementation retains a reference to Python object for a long as= =20 + the owning object exists. When the owning object is about to be freed, + registered Python objects are invalidated and reference dropped. */ +template > +class gdbpy_memoizing_registry_storage +{ +public: + using obj_type =3D P; + using val_type =3D V; + + void add (obj_type *obj) + { + gdb_assert (obj !=3D nullptr && obj->*val_slot !=3D nullptr); + + m_objects[obj->*val_slot] =3D obj; + Py_INCREF (obj); + } + + void remove (obj_type *obj) + { + gdb_assert_not_reached ("Should not be used."); + } + + obj_type *lookup (val_type *val) const + { + auto result =3D m_objects.find (val); + if (result !=3D m_objects.end ()) + return result->second; + else + return nullptr; + } + + ~gdbpy_memoizing_registry_storage () + { + Invalidator invalidate; + gdbpy_enter enter_py; + + for (auto each : m_objects) + { +=09invalidate (each.second); +=09Py_DECREF (each.second); + } + + m_objects.clear (); + } + +private: + std::unordered_map m_objects; +}; + #endif /* GDB_PYTHON_PYTHON_INTERNAL_H */ --=20 2.45.2