From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1879) id 41BB83858C5E; Fri, 20 Jan 2023 19:52:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 41BB83858C5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1674244357; bh=PK9qcRO69VuGNVnI+r1KoD/j32HOj3E7+CuRgJvAOYM=; h=From:To:Subject:Date:From; b=N4Q1enygqb8bEixHK5DnD30xliZrSCeKi5bVHnBXEkkv50E0p05kzFsoEhk2O64Ec dFmuFuWKL0EYwHBkXG5UV+QVYkxJEC4QKh5Ws/r98dOqUKaNOcZRXTo3mttZbvVxVL MXOFbv6K7DsfqVzkFIHkvhYzsDjeDeXClDkRNs40= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Simon Marchi To: gdb-cvs@sourceware.org Subject: [binutils-gdb] gdb: move frame_info_ptr to frame.{c,h} X-Act-Checkin: binutils-gdb X-Git-Author: Simon Marchi X-Git-Refname: refs/heads/master X-Git-Oldrev: 1298c32f01b3ae90fb17665f9b9b01c932767fd5 X-Git-Newrev: 43e8c9ce20357a12dc5ccaf9ac84eea2cb6aa39b Message-Id: <20230120195237.41BB83858C5E@sourceware.org> Date: Fri, 20 Jan 2023 19:52:37 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D43e8c9ce2035= 7a12dc5ccaf9ac84eea2cb6aa39b commit 43e8c9ce20357a12dc5ccaf9ac84eea2cb6aa39b Author: Simon Marchi Date: Tue Jan 3 12:48:48 2023 -0500 gdb: move frame_info_ptr to frame.{c,h} =20 A patch later in this series will make frame_info_ptr access some fields internal to frame_info, which we don't want to expose outside of frame.c. Move the frame_info_ptr class to frame.h, and the definitions to frame.c. Remove frame-info.c and frame-info.h. =20 Change-Id: Ic5949759e6262ea0da6123858702d48fe5673fea Reviewed-By: Bruno Larsen Diff: --- gdb/Makefile.in | 1 - gdb/c-lang.h | 1 + gdb/dwarf2/call-site.h | 2 +- gdb/frame-info.c | 65 --------------- gdb/frame-info.h | 211 ---------------------------------------------= ---- gdb/frame.c | 43 +++++++++- gdb/frame.h | 188 ++++++++++++++++++++++++++++++++++++++++++- gdb/gdbtypes.h | 2 - gdb/symtab.h | 1 + 9 files changed, 230 insertions(+), 284 deletions(-) diff --git a/gdb/Makefile.in b/gdb/Makefile.in index b22a6c624a6..cce85b87436 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1087,7 +1087,6 @@ COMMON_SFILES =3D \ findvar.c \ frame.c \ frame-base.c \ - frame-info.c \ frame-unwind.c \ gcore.c \ gdb-demangle.c \ diff --git a/gdb/c-lang.h b/gdb/c-lang.h index 8a82606b6d0..1d6b90cca19 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -25,6 +25,7 @@ struct ui_file; struct language_arch_info; struct type_print_options; struct parser_state; +struct compile_instance; =20 #include "compile/compile.h" #include "value.h" diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h index f5bee967594..c8a1e8b2971 100644 --- a/gdb/dwarf2/call-site.h +++ b/gdb/dwarf2/call-site.h @@ -23,8 +23,8 @@ #define CALL_SITE_H =20 #include "dwarf2/types.h" +#include "../frame.h" #include "gdbsupport/function-view.h" -#include "frame-info.h" =20 struct dwarf2_locexpr_baton; struct dwarf2_per_cu_data; diff --git a/gdb/frame-info.c b/gdb/frame-info.c deleted file mode 100644 index 99d92cd555d..00000000000 --- a/gdb/frame-info.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Frame info pointer - - Copyright (C) 2022-2023 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . = */ - -#include "defs.h" - -#include "frame-info.h" -#include "frame.h" - -/* See frame-info-ptr.h. */ - -intrusive_list frame_info_ptr::frame_list; - -/* See frame-info-ptr.h. */ - -void -frame_info_ptr::prepare_reinflate () -{ - m_cached_level =3D frame_relative_level (*this); - - if (m_cached_level !=3D 0) - m_cached_id =3D get_frame_id (*this); -} - -/* See frame-info-ptr.h. */ - -void -frame_info_ptr::reinflate () -{ - /* Ensure we have a valid frame level (sentinel frame or above), indicat= ing - prepare_reinflate was called. */ - gdb_assert (m_cached_level >=3D -1); - - if (m_ptr !=3D nullptr) - { - /* The frame_info wasn't invalidated, no need to reinflate. */ - return; - } - - /* Frame #0 needs special handling, see comment in select_frame. */ - if (m_cached_level =3D=3D 0) - m_ptr =3D get_current_frame ().get (); - else - { - gdb_assert (frame_id_p (m_cached_id)); - m_ptr =3D frame_find_by_id (m_cached_id).get (); - } - - gdb_assert (m_ptr !=3D nullptr); -} diff --git a/gdb/frame-info.h b/gdb/frame-info.h deleted file mode 100644 index d0fe9d6a85e..00000000000 --- a/gdb/frame-info.h +++ /dev/null @@ -1,211 +0,0 @@ -/* Frame info pointer - - Copyright (C) 2022-2023 Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . = */ - -#ifndef GDB_FRAME_INFO_H -#define GDB_FRAME_INFO_H - -#include "gdbsupport/intrusive_list.h" -#include "frame-id.h" - -struct frame_info; - -/* A wrapper for "frame_info *". frame_info objects are invalidated - whenever reinit_frame_cache is called. This class arranges to - invalidate the pointer when appropriate. This is done to help - detect a GDB bug that was relatively common. - - A small amount of code must still operate on raw pointers, so a - "get" method is provided. However, you should normally not use - this in new code. */ - -class frame_info_ptr : public intrusive_list_node -{ -public: - /* Create a frame_info_ptr from a raw pointer. */ - explicit frame_info_ptr (struct frame_info *ptr) - : m_ptr (ptr) - { - frame_list.push_back (*this); - } - - /* Create a null frame_info_ptr. */ - frame_info_ptr () - { - frame_list.push_back (*this); - } - - frame_info_ptr (std::nullptr_t) - { - frame_list.push_back (*this); - } - - frame_info_ptr (const frame_info_ptr &other) - : m_ptr (other.m_ptr), - m_cached_id (other.m_cached_id), - m_cached_level (other.m_cached_level) - { - frame_list.push_back (*this); - } - - frame_info_ptr (frame_info_ptr &&other) - : m_ptr (other.m_ptr), - m_cached_id (other.m_cached_id), - m_cached_level (other.m_cached_level) - { - other.m_ptr =3D nullptr; - other.m_cached_id =3D null_frame_id; - other.m_cached_level =3D invalid_level; - frame_list.push_back (*this); - } - - ~frame_info_ptr () - { - /* If this node has static storage, it may be deleted after - frame_list. Attempting to erase ourselves would then trigger - internal errors, so make sure we are still linked first. */ - if (is_linked ()) - frame_list.erase (frame_list.iterator_to (*this)); - } - - frame_info_ptr &operator=3D (const frame_info_ptr &other) - { - m_ptr =3D other.m_ptr; - m_cached_id =3D other.m_cached_id; - m_cached_level =3D other.m_cached_level; - return *this; - } - - frame_info_ptr &operator=3D (std::nullptr_t) - { - m_ptr =3D nullptr; - m_cached_id =3D null_frame_id; - m_cached_level =3D invalid_level; - return *this; - } - - frame_info_ptr &operator=3D (frame_info_ptr &&other) - { - m_ptr =3D other.m_ptr; - m_cached_id =3D other.m_cached_id; - m_cached_level =3D other.m_cached_level; - other.m_ptr =3D nullptr; - other.m_cached_id =3D null_frame_id; - other.m_cached_level =3D invalid_level; - return *this; - } - - frame_info *operator-> () const - { - return m_ptr; - } - - /* Fetch the underlying pointer. Note that new code should - generally not use this -- avoid it if at all possible. */ - frame_info *get () const - { - return m_ptr; - } - - /* This exists for compatibility with pre-existing code that checked - a "frame_info *" using "!". */ - bool operator! () const - { - return m_ptr =3D=3D nullptr; - } - - /* This exists for compatibility with pre-existing code that checked - a "frame_info *" like "if (ptr)". */ - explicit operator bool () const - { - return m_ptr !=3D nullptr; - } - - /* Invalidate this pointer. */ - void invalidate () - { - m_ptr =3D nullptr; - } - - /* Cache the frame_id that the pointer will use to reinflate. */ - void prepare_reinflate (); - - /* Use the cached frame_id to reinflate the pointer. */ - void reinflate (); - -private: - /* We sometimes need to construct frame_info_ptr objects around the - sentinel_frame, which has level -1. Therefore, make the invalid frame - level value -2. */ - static constexpr int invalid_level =3D -2; - - /* The underlying pointer. */ - frame_info *m_ptr =3D nullptr; - - /* The frame_id of the underlying pointer. */ - frame_id m_cached_id =3D null_frame_id; - - /* The frame level of the underlying pointer. */ - int m_cached_level =3D invalid_level; - - /* All frame_info_ptr objects are kept on an intrusive list. - This keeps their construction and destruction costs - reasonably small. */ - static intrusive_list frame_list; - - /* A friend so it can invalidate the pointers. */ - friend void reinit_frame_cache (); -}; - -static inline bool -operator=3D=3D (const frame_info *self, const frame_info_ptr &other) -{ - return self =3D=3D other.get (); -} - -static inline bool -operator=3D=3D (const frame_info_ptr &self, const frame_info_ptr &other) -{ - return self.get () =3D=3D other.get (); -} - -static inline bool -operator=3D=3D (const frame_info_ptr &self, const frame_info *other) -{ - return self.get () =3D=3D other; -} - -static inline bool -operator!=3D (const frame_info *self, const frame_info_ptr &other) -{ - return self !=3D other.get (); -} - -static inline bool -operator!=3D (const frame_info_ptr &self, const frame_info_ptr &other) -{ - return self.get () !=3D other.get (); -} - -static inline bool -operator!=3D (const frame_info_ptr &self, const frame_info *other) -{ - return self.get () !=3D other; -} - -#endif /* GDB_FRAME_INFO_H */ diff --git a/gdb/frame.c b/gdb/frame.c index 2f9622ad2b2..b5f48399703 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -19,7 +19,6 @@ =20 #include "defs.h" #include "frame.h" -#include "frame-info.h" #include "target.h" #include "value.h" #include "inferior.h" /* for inferior_ptid */ @@ -3161,6 +3160,48 @@ maintenance_print_frame_id (const char *args, int fr= om_tty) get_frame_id (frame).to_string ().c_str ()); } =20 +/* See frame-info-ptr.h. */ + +intrusive_list frame_info_ptr::frame_list; + +/* See frame-info-ptr.h. */ + +void +frame_info_ptr::prepare_reinflate () +{ + m_cached_level =3D frame_relative_level (*this); + + if (m_cached_level !=3D 0) + m_cached_id =3D get_frame_id (*this); +} + +/* See frame-info-ptr.h. */ + +void +frame_info_ptr::reinflate () +{ + /* Ensure we have a valid frame level (sentinel frame or above), indicat= ing + prepare_reinflate was called. */ + gdb_assert (m_cached_level >=3D -1); + + if (m_ptr !=3D nullptr) + { + /* The frame_info wasn't invalidated, no need to reinflate. */ + return; + } + + /* Frame #0 needs special handling, see comment in select_frame. */ + if (m_cached_level =3D=3D 0) + m_ptr =3D get_current_frame ().get (); + else + { + gdb_assert (frame_id_p (m_cached_id)); + m_ptr =3D frame_find_by_id (m_cached_id).get (); + } + + gdb_assert (m_ptr !=3D nullptr); +} + void _initialize_frame (); void _initialize_frame () diff --git a/gdb/frame.h b/gdb/frame.h index 2c2e320bf7d..70ad606c134 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -20,8 +20,6 @@ #if !defined (FRAME_H) #define FRAME_H 1 =20 -#include "frame-info.h" - /* The following is the intended naming schema for frame functions. It isn't 100% consistent, but it is approaching that. Frame naming schema: @@ -72,7 +70,9 @@ */ =20 #include "cli/cli-option.h" +#include "frame-id.h" #include "gdbsupport/common-debug.h" +#include "gdbsupport/intrusive_list.h" =20 struct symtab_and_line; struct frame_unwind; @@ -85,7 +85,6 @@ struct frame_print_options; =20 /* The frame object. */ =20 -class frame_info_ptr; =20 /* Save and restore the currently selected frame. */ =20 @@ -194,6 +193,189 @@ enum frame_type SENTINEL_FRAME }; =20 +/* A wrapper for "frame_info *". frame_info objects are invalidated + whenever reinit_frame_cache is called. This class arranges to + invalidate the pointer when appropriate. This is done to help + detect a GDB bug that was relatively common. + + A small amount of code must still operate on raw pointers, so a + "get" method is provided. However, you should normally not use + this in new code. */ + +class frame_info_ptr : public intrusive_list_node +{ +public: + /* Create a frame_info_ptr from a raw pointer. */ + explicit frame_info_ptr (struct frame_info *ptr) + : m_ptr (ptr) + { + frame_list.push_back (*this); + } + + /* Create a null frame_info_ptr. */ + frame_info_ptr () + { + frame_list.push_back (*this); + } + + frame_info_ptr (std::nullptr_t) + { + frame_list.push_back (*this); + } + + frame_info_ptr (const frame_info_ptr &other) + : m_ptr (other.m_ptr), + m_cached_id (other.m_cached_id), + m_cached_level (other.m_cached_level) + { + frame_list.push_back (*this); + } + + frame_info_ptr (frame_info_ptr &&other) + : m_ptr (other.m_ptr), + m_cached_id (other.m_cached_id), + m_cached_level (other.m_cached_level) + { + other.m_ptr =3D nullptr; + other.m_cached_id =3D null_frame_id; + other.m_cached_level =3D invalid_level; + frame_list.push_back (*this); + } + + ~frame_info_ptr () + { + /* If this node has static storage, it may be deleted after + frame_list. Attempting to erase ourselves would then trigger + internal errors, so make sure we are still linked first. */ + if (is_linked ()) + frame_list.erase (frame_list.iterator_to (*this)); + } + + frame_info_ptr &operator=3D (const frame_info_ptr &other) + { + m_ptr =3D other.m_ptr; + m_cached_id =3D other.m_cached_id; + m_cached_level =3D other.m_cached_level; + return *this; + } + + frame_info_ptr &operator=3D (std::nullptr_t) + { + m_ptr =3D nullptr; + m_cached_id =3D null_frame_id; + m_cached_level =3D invalid_level; + return *this; + } + + frame_info_ptr &operator=3D (frame_info_ptr &&other) + { + m_ptr =3D other.m_ptr; + m_cached_id =3D other.m_cached_id; + m_cached_level =3D other.m_cached_level; + other.m_ptr =3D nullptr; + other.m_cached_id =3D null_frame_id; + other.m_cached_level =3D invalid_level; + return *this; + } + + frame_info *operator-> () const + { + return m_ptr; + } + + /* Fetch the underlying pointer. Note that new code should + generally not use this -- avoid it if at all possible. */ + frame_info *get () const + { + return m_ptr; + } + + /* This exists for compatibility with pre-existing code that checked + a "frame_info *" using "!". */ + bool operator! () const + { + return m_ptr =3D=3D nullptr; + } + + /* This exists for compatibility with pre-existing code that checked + a "frame_info *" like "if (ptr)". */ + explicit operator bool () const + { + return m_ptr !=3D nullptr; + } + + /* Invalidate this pointer. */ + void invalidate () + { + m_ptr =3D nullptr; + } + + /* Cache the frame_id that the pointer will use to reinflate. */ + void prepare_reinflate (); + + /* Use the cached frame_id to reinflate the pointer. */ + void reinflate (); + +private: + /* We sometimes need to construct frame_info_ptr objects around the + sentinel_frame, which has level -1. Therefore, make the invalid frame + level value -2. */ + static constexpr int invalid_level =3D -2; + + /* The underlying pointer. */ + frame_info *m_ptr =3D nullptr; + + /* The frame_id of the underlying pointer. */ + frame_id m_cached_id =3D null_frame_id; + + /* The frame level of the underlying pointer. */ + int m_cached_level =3D invalid_level; + + /* All frame_info_ptr objects are kept on an intrusive list. + This keeps their construction and destruction costs + reasonably small. */ + static intrusive_list frame_list; + + /* A friend so it can invalidate the pointers. */ + friend void reinit_frame_cache (); +}; + +static inline bool +operator=3D=3D (const frame_info *self, const frame_info_ptr &other) +{ + return self =3D=3D other.get (); +} + +static inline bool +operator=3D=3D (const frame_info_ptr &self, const frame_info_ptr &other) +{ + return self.get () =3D=3D other.get (); +} + +static inline bool +operator=3D=3D (const frame_info_ptr &self, const frame_info *other) +{ + return self.get () =3D=3D other; +} + +static inline bool +operator!=3D (const frame_info *self, const frame_info_ptr &other) +{ + return self !=3D other.get (); +} + +static inline bool +operator!=3D (const frame_info_ptr &self, const frame_info_ptr &other) +{ + return self.get () !=3D other.get (); +} + +static inline bool +operator!=3D (const frame_info_ptr &self, const frame_info *other) +{ + return self.get () !=3D other; +} + /* For every stopped thread, GDB tracks two frames: current and selected. Current frame is the inner most frame of the selected thread. Selected frame is the one being examined by the GDB diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 6b643fcdaee..18ea1bca19c 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -56,7 +56,6 @@ #include "dwarf2.h" #include "gdbsupport/gdb_obstack.h" #include "gmp-utils.h" -#include "frame-info.h" =20 /* Forward declarations for prototypes. */ struct field; @@ -1734,7 +1733,6 @@ struct func_type struct type *self_type; }; =20 - /* The type-specific info for TYPE_CODE_FIXED_POINT types. */ =20 struct fixed_point_type_info diff --git a/gdb/symtab.h b/gdb/symtab.h index ae3a81991df..3ba40bd9af5 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -37,6 +37,7 @@ #include "completer.h" #include "gdb-demangle.h" #include "split-name.h" +#include "frame.h" =20 /* Opaque declarations. */ struct ui_file;