From patchwork Tue May 9 17:46:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Arnez X-Patchwork-Id: 20350 Received: (qmail 122110 invoked by alias); 9 May 2017 17:56:36 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 122092 invoked by uid 89); 9 May 2017 17:56:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=preparations X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 May 2017 17:56:34 +0000 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id v49Hrs77087241 for ; Tue, 9 May 2017 13:56:35 -0400 Received: from e06smtp14.uk.ibm.com (e06smtp14.uk.ibm.com [195.75.94.110]) by mx0a-001b2d01.pphosted.com with ESMTP id 2abfbdrxym-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 09 May 2017 13:56:35 -0400 Received: from localhost by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 9 May 2017 18:56:33 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp14.uk.ibm.com (192.168.101.144) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 9 May 2017 18:56:32 +0100 Received: from d06av21.portsmouth.uk.ibm.com (d06av21.portsmouth.uk.ibm.com [9.149.105.232]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v49HuV6v15991048 for ; Tue, 9 May 2017 17:56:31 GMT Received: from d06av21.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2E9AB52043 for ; Tue, 9 May 2017 17:53:55 +0100 (BST) Received: from oc1027705133.ibm.com (unknown [9.152.212.109]) by d06av21.portsmouth.uk.ibm.com (Postfix) with ESMTP id 151085203F for ; Tue, 9 May 2017 17:53:55 +0100 (BST) From: Andreas Arnez To: gdb-patches@sourceware.org Subject: [PATCH v2 14/19] read/write_pieced_value: Improve logic for buffer allocation Date: Tue, 9 May 2017 19:46:10 +0200 In-Reply-To: <1494352015-10465-1-git-send-email-arnez@linux.vnet.ibm.com> References: <1494352015-10465-1-git-send-email-arnez@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17050917-0016-0000-0000-000004978292 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17050917-0017-0000-0000-00002796E8C8 Message-Id: <1494352015-10465-15-git-send-email-arnez@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-05-09_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705090098 X-IsSubscribed: yes So far the main loop in read_pieced_value and write_pieced_value is structured like this: (1) Prepare a buffer and some variables we may need; (2) depending on the DWARF piece type to be handled, use the buffer and the prepared variables, ignore them, or even recalculate them. This approach reduces readability and may also lead to unnecessary copying of data. This patch moves the preparations to the places where sufficient information is available and removes some of the variables involved. gdb/ChangeLog: * dwarf2loc.c (read_pieced_value): Move the buffer allocation and some other preparations to the places where sufficient information is available. (write_pieced_value): Likewise. --- gdb/dwarf2loc.c | 108 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 62462f0..3255274 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1794,8 +1794,7 @@ read_pieced_value (struct value *v) { struct dwarf_expr_piece *p = &c->pieces[i]; size_t this_size, this_size_bits; - long dest_offset_bits, source_offset_bits, source_offset; - const gdb_byte *intermediate_buffer; + long dest_offset_bits, source_offset_bits; /* Compute size, source, and destination offsets for copying, in bits. */ @@ -1813,11 +1812,6 @@ read_pieced_value (struct value *v) if (this_size_bits > max_offset - offset) this_size_bits = max_offset - offset; - this_size = bits_to_bytes (source_offset_bits, this_size_bits); - buffer.reserve (this_size); - source_offset = source_offset_bits / 8; - intermediate_buffer = buffer.data (); - /* Copy from the source to DEST_BUFFER. */ switch (p->location) { @@ -1843,13 +1837,11 @@ read_pieced_value (struct value *v) this_size, buffer.data (), &optim, &unavail)) { - /* Just so garbage doesn't ever shine through. */ - memset (buffer.data (), 0, this_size); - if (optim) mark_value_bits_optimized_out (v, offset, this_size_bits); if (unavail) mark_value_bits_unavailable (v, offset, this_size_bits); + break; } copy_bitwise (contents, dest_offset_bits, @@ -1859,12 +1851,15 @@ read_pieced_value (struct value *v) break; case DWARF_VALUE_MEMORY: + this_size = bits_to_bytes (source_offset_bits, this_size_bits); + buffer.reserve (this_size); + read_value_memory (v, offset, p->v.mem.in_stack_memory, - p->v.mem.addr + source_offset, + p->v.mem.addr + source_offset_bits / 8, buffer.data (), this_size); copy_bitwise (contents, dest_offset_bits, - intermediate_buffer, source_offset_bits % 8, + buffer.data (), source_offset_bits % 8, this_size_bits, bits_big_endian); break; @@ -1892,18 +1887,18 @@ read_pieced_value (struct value *v) case DWARF_VALUE_LITERAL: { - size_t n = this_size; + ULONGEST literal_size_bits = 8 * p->v.literal.length; + size_t n = this_size_bits; - if (n > p->v.literal.length - source_offset) - n = (p->v.literal.length >= source_offset - ? p->v.literal.length - source_offset - : 0); - if (n != 0) - intermediate_buffer = p->v.literal.data + source_offset; + /* Cut off at the end of the implicit value. */ + if (source_offset_bits >= literal_size_bits) + break; + if (n > literal_size_bits - source_offset_bits) + n = literal_size_bits - source_offset_bits; copy_bitwise (contents, dest_offset_bits, - intermediate_buffer, source_offset_bits % 8, - this_size_bits, bits_big_endian); + p->v.literal.data, source_offset_bits, + n, bits_big_endian); } break; @@ -1960,9 +1955,7 @@ write_pieced_value (struct value *to, struct value *from) { struct dwarf_expr_piece *p = &c->pieces[i]; size_t this_size_bits, this_size; - long dest_offset_bits, source_offset_bits, dest_offset, source_offset; - int need_bitwise; - const gdb_byte *source_buffer; + long dest_offset_bits, source_offset_bits; this_size_bits = p->size; if (bits_to_skip > 0 && bits_to_skip >= this_size_bits) @@ -1978,22 +1971,6 @@ write_pieced_value (struct value *to, struct value *from) if (this_size_bits > max_offset - offset) this_size_bits = max_offset - offset; - this_size = bits_to_bytes (dest_offset_bits, this_size_bits); - source_offset = source_offset_bits / 8; - dest_offset = dest_offset_bits / 8; - if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0 - && this_size_bits % 8 == 0) - { - source_buffer = contents + source_offset; - need_bitwise = 0; - } - else - { - buffer.reserve (this_size); - source_buffer = buffer.data (); - need_bitwise = 1; - } - switch (p->location) { case DWARF_VALUE_REGISTER: @@ -2045,21 +2022,44 @@ write_pieced_value (struct value *to, struct value *from) } break; case DWARF_VALUE_MEMORY: - if (need_bitwise) - { - /* Only the first and last bytes can possibly have any - bits reused. */ - read_memory (p->v.mem.addr + dest_offset, buffer.data (), 1); - read_memory (p->v.mem.addr + dest_offset + this_size - 1, - &buffer[this_size - 1], 1); - copy_bitwise (buffer.data (), dest_offset_bits % 8, - contents, source_offset_bits, - this_size_bits, - bits_big_endian); - } + { + CORE_ADDR start_addr = p->v.mem.addr + dest_offset_bits / 8; - write_memory (p->v.mem.addr + dest_offset, - source_buffer, this_size); + if (dest_offset_bits % 8 == 0 && this_size_bits % 8 == 0 + && source_offset_bits % 8 == 0) + { + /* Everything is byte-aligned; no buffer needed. */ + write_memory (start_addr, + contents + source_offset_bits / 8, + this_size_bits / 8); + break; + } + + this_size = bits_to_bytes (dest_offset_bits, this_size_bits); + buffer.reserve (this_size); + + if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0) + { + if (this_size <= 8) + { + /* Perform a single read for small sizes. */ + read_memory (start_addr, buffer.data (), this_size); + } + else + { + /* Only the first and last bytes can possibly have any + bits reused. */ + read_memory (start_addr, buffer.data (), 1); + read_memory (start_addr + this_size - 1, + &buffer[this_size - 1], 1); + } + } + + copy_bitwise (buffer.data (), dest_offset_bits % 8, + contents, source_offset_bits, + this_size_bits, bits_big_endian); + write_memory (start_addr, buffer.data (), this_size); + } break; default: mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to)));