From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15739 invoked by alias); 21 Jun 2018 09:39:05 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 15627 invoked by uid 89); 21 Jun 2018 09:39:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.0 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 spammy=35810 X-HELO: EUR01-HE1-obe.outbound.protection.outlook.com Received: from mail-he1eur01on0064.outbound.protection.outlook.com (HELO EUR01-HE1-obe.outbound.protection.outlook.com) (104.47.0.64) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 21 Jun 2018 09:39:02 +0000 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; Received: from C02TF0U7HF1T.manchester.arm.com (217.140.96.140) by AM4PR0802MB2131.eurprd08.prod.outlook.com (2603:10a6:200:5c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.863.16; Thu, 21 Jun 2018 09:38:53 +0000 From: Alan Hayward To: gdb-patches@sourceware.org Cc: nd@arm.com, Alan Hayward Subject: [PATCH v2 2/3] Avoid memcpys in regcache read_part/write_part for full registers. Date: Thu, 21 Jun 2018 09:39:00 -0000 Message-Id: <20180621093802.79342-3-alan.hayward@arm.com> In-Reply-To: <20180621093802.79342-1-alan.hayward@arm.com> References: <20180621093802.79342-1-alan.hayward@arm.com> MIME-Version: 1.0 Content-Type: text/plain X-ClientProxiedBy: CWLP265CA0232.GBRP265.PROD.OUTLOOK.COM (2603:10a6:401:4f::28) To AM4PR0802MB2131.eurprd08.prod.outlook.com (2603:10a6:200:5c::22) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c8bdc50a-05f5-497a-2846-08d5d75acd29 X-MS-TrafficTypeDiagnostic: AM4PR0802MB2131: NoDisclaimer: True X-Exchange-Antispam-Report-Test: UriScan:(180628864354917); X-MS-Exchange-SenderADCheck: 1 X-Forefront-PRVS: 07106EF9B9 Received-SPF: None (protection.outlook.com: arm.com does not designate permitted sender hosts) SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Jun 2018 09:38:53.0086 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c8bdc50a-05f5-497a-2846-08d5d75acd29 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM4PR0802MB2131 X-IsSubscribed: yes X-SW-Source: 2018-06/txt/msg00511.txt.bz2 Additionally, tidy up the functions: Remove asserts, use gdb_byte, update comments. 2018-06-21 Alan Hayward * regcache.c (readable_regcache::read_part): Avoid memcpy when possible. (regcache::write_part): Likewise. (readable_regcache::cooked_read_part): Update comment. (readable_regcache::cooked_write_part): Likewise. * regcache.h: (readable_regcache::read_part): Likewise. (regcache::write_part): Likewise. --- gdb/regcache.c | 92 ++++++++++++++++++++++++++++++---------------------------- gdb/regcache.h | 12 +++++--- 2 files changed, 55 insertions(+), 49 deletions(-) diff --git a/gdb/regcache.c b/gdb/regcache.c index 6276b149a2..fe4742c2ee 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -775,77 +775,75 @@ regcache::cooked_write (int regnum, const gdb_byte *buf) regnum, buf); } -/* Perform a partial register transfer using a read, modify, write - operation. */ +/* See regcache.h. */ enum register_status -readable_regcache::read_part (int regnum, int offset, int len, void *in, - bool is_raw) +readable_regcache::read_part (int regnum, int offset, int len, + gdb_byte *out, bool is_raw) { - struct gdbarch *gdbarch = arch (); - gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum)); + int reg_size = register_size (arch (), regnum); - gdb_assert (in != NULL); - gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]); - gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]); - /* Something to do? */ - if (offset + len == 0) + gdb_assert (out != NULL); + gdb_assert (offset >= 0 && len >= 0 && offset + len <= reg_size); + + if (offset == 0 && len == 0) return REG_VALID; - /* Read (when needed) ... */ + + if (offset == 0 && len == reg_size) + return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out); + enum register_status status; + gdb_byte *reg = (gdb_byte *) alloca (reg_size); - if (is_raw) - status = raw_read (regnum, reg); - else - status = cooked_read (regnum, reg); + /* Read full register to buffer. */ + status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg); if (status != REG_VALID) return status; - /* ... modify ... */ - memcpy (in, reg + offset, len); - + /* Copy out. */ + memcpy (out, reg + offset, len); return REG_VALID; } +/* See regcache.h. */ + enum register_status regcache::write_part (int regnum, int offset, int len, - const void *out, bool is_raw) + const gdb_byte *in, bool is_raw) { - struct gdbarch *gdbarch = arch (); - gdb_byte *reg = (gdb_byte *) alloca (register_size (gdbarch, regnum)); + int reg_size = register_size (arch (), regnum); - gdb_assert (out != NULL); - gdb_assert (offset >= 0 && offset <= m_descr->sizeof_register[regnum]); - gdb_assert (len >= 0 && offset + len <= m_descr->sizeof_register[regnum]); - /* Something to do? */ - if (offset + len == 0) + gdb_assert (in != NULL); + gdb_assert (offset >= 0 && len >= 0 && offset + len <= reg_size); + + if (offset == 0 && len == 0) return REG_VALID; - /* Read (when needed) ... */ - if (offset > 0 - || offset + len < m_descr->sizeof_register[regnum]) - { - enum register_status status; - if (is_raw) - status = raw_read (regnum, reg); - else - status = cooked_read (regnum, reg); - if (status != REG_VALID) - return status; + if (offset == 0 && len == reg_size) + { + (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in); + return REG_VALID; } - memcpy (reg + offset, out, len); - /* ... write (when needed). */ - if (is_raw) - raw_write (regnum, reg); - else - cooked_write (regnum, reg); + enum register_status status; + gdb_byte *reg = (gdb_byte *) alloca (reg_size); + + /* Read existing register to buffer. */ + status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg); + if (status != REG_VALID) + return status; + /* Update buffer, then write back to regcache. */ + memcpy (reg + offset, in, len); + is_raw ? raw_write (regnum, reg) : cooked_write (regnum, reg); return REG_VALID; } +/* See regcache.h. */ + enum register_status -readable_regcache::raw_read_part (int regnum, int offset, int len, gdb_byte *buf) +readable_regcache::raw_read_part (int regnum, int offset, int len, + gdb_byte *buf) { assert_regnum (regnum); return read_part (regnum, offset, len, buf, true); @@ -861,6 +859,8 @@ regcache::raw_write_part (int regnum, int offset, int len, write_part (regnum, offset, len, buf, true); } +/* See regcache.h. */ + enum register_status readable_regcache::cooked_read_part (int regnum, int offset, int len, gdb_byte *buf) @@ -869,6 +869,8 @@ readable_regcache::cooked_read_part (int regnum, int offset, int len, return read_part (regnum, offset, len, buf, false); } +/* See regcache.h. */ + void regcache::cooked_write_part (int regnum, int offset, int len, const gdb_byte *buf) diff --git a/gdb/regcache.h b/gdb/regcache.h index 35c41888a7..c17ce09dee 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -253,8 +253,11 @@ public: struct value *cooked_read_value (int regnum); protected: - enum register_status read_part (int regnum, int offset, int len, void *in, - bool is_raw); + + /* Perform a partial register transfer using a read, modify, write + operation. Will fail if register is currently invalid. */ + enum register_status read_part (int regnum, int offset, int len, + gdb_byte *out, bool is_raw); }; /* Buffer of registers, can be read and written. */ @@ -355,9 +358,10 @@ private: int regnum, const void *in_buf, void *out_buf, size_t size) const; + /* Perform a partial register transfer using a read, modify, write + operation. */ enum register_status write_part (int regnum, int offset, int len, - const void *out, bool is_raw); - + const gdb_byte *out, bool is_raw); /* The address space of this register cache (for registers where it makes sense, like PC or SP). */ -- 2.15.2 (Apple Git-101.1)