This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] read/write_pieced_value: Improve logic for buffer allocation


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=242d31ab7c3901e02bd68c1824d1d3610e02562b

commit 242d31ab7c3901e02bd68c1824d1d3610e02562b
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
Date:   Tue Jun 13 15:20:30 2017 +0200

    read/write_pieced_value: Improve logic for buffer allocation
    
    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.

Diff:
---
 gdb/ChangeLog   |   7 ++++
 gdb/dwarf2loc.c | 110 ++++++++++++++++++++++++++++----------------------------
 2 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 8c022a4..a177e8e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
 2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
+	* 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.
+
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
 	* dwarf2loc.c (bits_to_bytes): New function.
 	(read_pieced_value): Fix offset calculations for register pieces
 	on big-endian targets.
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index a7447cb..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,24 +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;
-
-      /* Check whether the data can be transferred byte-wise.  */
-      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:
@@ -2047,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;
+
+	    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);
 
-	  write_memory (p->v.mem.addr + dest_offset,
-			source_buffer, 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)));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]