Blame SOURCES/gdb-rhbz1420304-s390x-22of35.patch

e1d87d
commit 242d31ab7c3901e02bd68c1824d1d3610e02562b
e1d87d
Author: Andreas Arnez <arnez@linux.vnet.ibm.com>
e1d87d
Date:   Tue Jun 13 15:20:30 2017 +0200
e1d87d
e1d87d
    read/write_pieced_value: Improve logic for buffer allocation
e1d87d
    
e1d87d
    So far the main loop in read_pieced_value and write_pieced_value is
e1d87d
    structured like this:
e1d87d
    
e1d87d
    (1) Prepare a buffer and some variables we may need;
e1d87d
    
e1d87d
    (2) depending on the DWARF piece type to be handled, use the buffer and
e1d87d
        the prepared variables, ignore them, or even recalculate them.
e1d87d
    
e1d87d
    This approach reduces readability and may also lead to unnecessary copying
e1d87d
    of data.  This patch moves the preparations to the places where sufficient
e1d87d
    information is available and removes some of the variables involved.
e1d87d
    
e1d87d
    gdb/ChangeLog:
e1d87d
    
e1d87d
            * dwarf2loc.c (read_pieced_value): Move the buffer allocation and
e1d87d
            some other preparations to the places where sufficient information
e1d87d
            is available.
e1d87d
            (write_pieced_value): Likewise.
e1d87d
e1d87d
### a/gdb/ChangeLog
e1d87d
### b/gdb/ChangeLog
e1d87d
## -1,5 +1,12 @@
e1d87d
 2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
 
e1d87d
+	* dwarf2loc.c (read_pieced_value): Move the buffer allocation and
e1d87d
+	some other preparations to the places where sufficient information
e1d87d
+	is available.
e1d87d
+	(write_pieced_value): Likewise.
e1d87d
+
e1d87d
+2017-06-13  Andreas Arnez  <arnez@linux.vnet.ibm.com>
e1d87d
+
e1d87d
 	* dwarf2loc.c (bits_to_bytes): New function.
e1d87d
 	(read_pieced_value): Fix offset calculations for register pieces
e1d87d
 	on big-endian targets.
e1d87d
--- a/gdb/dwarf2loc.c
e1d87d
+++ b/gdb/dwarf2loc.c
e1d87d
@@ -1794,8 +1794,7 @@ read_pieced_value (struct value *v)
e1d87d
     {
e1d87d
       struct dwarf_expr_piece *p = &c->pieces[i];
e1d87d
       size_t this_size, this_size_bits;
e1d87d
-      long dest_offset_bits, source_offset_bits, source_offset;
e1d87d
-      const gdb_byte *intermediate_buffer;
e1d87d
+      long dest_offset_bits, source_offset_bits;
e1d87d
 
e1d87d
       /* Compute size, source, and destination offsets for copying, in
e1d87d
 	 bits.  */
e1d87d
@@ -1813,11 +1812,6 @@ read_pieced_value (struct value *v)
e1d87d
       if (this_size_bits > max_offset - offset)
e1d87d
 	this_size_bits = max_offset - offset;
e1d87d
 
e1d87d
-      this_size = bits_to_bytes (source_offset_bits, this_size_bits);
e1d87d
-      buffer.reserve (this_size);
e1d87d
-      source_offset = source_offset_bits / 8;
e1d87d
-      intermediate_buffer = buffer.data ();
e1d87d
-
e1d87d
       /* Copy from the source to DEST_BUFFER.  */
e1d87d
       switch (p->location)
e1d87d
 	{
e1d87d
@@ -1843,13 +1837,11 @@ read_pieced_value (struct value *v)
e1d87d
 					   this_size, buffer.data (),
e1d87d
 					   &optim, &unavail))
e1d87d
 	      {
e1d87d
-		/* Just so garbage doesn't ever shine through.  */
e1d87d
-		memset (buffer.data (), 0, this_size);
e1d87d
-
e1d87d
 		if (optim)
e1d87d
 		  mark_value_bits_optimized_out (v, offset, this_size_bits);
e1d87d
 		if (unavail)
e1d87d
 		  mark_value_bits_unavailable (v, offset, this_size_bits);
e1d87d
+		break;
e1d87d
 	      }
e1d87d
 
e1d87d
 	    copy_bitwise (contents, dest_offset_bits,
e1d87d
@@ -1859,12 +1851,15 @@ read_pieced_value (struct value *v)
e1d87d
 	  break;
e1d87d
 
e1d87d
 	case DWARF_VALUE_MEMORY:
e1d87d
+	  this_size = bits_to_bytes (source_offset_bits, this_size_bits);
e1d87d
+	  buffer.reserve (this_size);
e1d87d
+
e1d87d
 	  read_value_memory (v, offset,
e1d87d
 			     p->v.mem.in_stack_memory,
e1d87d
-			     p->v.mem.addr + source_offset,
e1d87d
+			     p->v.mem.addr + source_offset_bits / 8,
e1d87d
 			     buffer.data (), this_size);
e1d87d
 	  copy_bitwise (contents, dest_offset_bits,
e1d87d
-			intermediate_buffer, source_offset_bits % 8,
e1d87d
+			buffer.data (), source_offset_bits % 8,
e1d87d
 			this_size_bits, bits_big_endian);
e1d87d
 	  break;
e1d87d
 
e1d87d
@@ -1892,18 +1887,18 @@ read_pieced_value (struct value *v)
e1d87d
 
e1d87d
 	case DWARF_VALUE_LITERAL:
e1d87d
 	  {
e1d87d
-	    size_t n = this_size;
e1d87d
+	    ULONGEST literal_size_bits = 8 * p->v.literal.length;
e1d87d
+	    size_t n = this_size_bits;
e1d87d
 
e1d87d
-	    if (n > p->v.literal.length - source_offset)
e1d87d
-	      n = (p->v.literal.length >= source_offset
e1d87d
-		   ? p->v.literal.length - source_offset
e1d87d
-		   : 0);
e1d87d
-	    if (n != 0)
e1d87d
-	      intermediate_buffer = p->v.literal.data + source_offset;
e1d87d
+	    /* Cut off at the end of the implicit value.  */
e1d87d
+	    if (source_offset_bits >= literal_size_bits)
e1d87d
+	      break;
e1d87d
+	    if (n > literal_size_bits - source_offset_bits)
e1d87d
+	      n = literal_size_bits - source_offset_bits;
e1d87d
 
e1d87d
 	    copy_bitwise (contents, dest_offset_bits,
e1d87d
-			  intermediate_buffer, source_offset_bits % 8,
e1d87d
-			  this_size_bits, bits_big_endian);
e1d87d
+			  p->v.literal.data, source_offset_bits,
e1d87d
+			  n, bits_big_endian);
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 
e1d87d
@@ -1960,9 +1955,7 @@ write_pieced_value (struct value *to, struct value *from)
e1d87d
     {
e1d87d
       struct dwarf_expr_piece *p = &c->pieces[i];
e1d87d
       size_t this_size_bits, this_size;
e1d87d
-      long dest_offset_bits, source_offset_bits, dest_offset, source_offset;
e1d87d
-      int need_bitwise;
e1d87d
-      const gdb_byte *source_buffer;
e1d87d
+      long dest_offset_bits, source_offset_bits;
e1d87d
 
e1d87d
       this_size_bits = p->size;
e1d87d
       if (bits_to_skip > 0 && bits_to_skip >= this_size_bits)
e1d87d
@@ -1978,24 +1971,6 @@ write_pieced_value (struct value *to, struct value *from)
e1d87d
       if (this_size_bits > max_offset - offset)
e1d87d
 	this_size_bits = max_offset - offset;
e1d87d
 
e1d87d
-      this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
e1d87d
-      source_offset = source_offset_bits / 8;
e1d87d
-      dest_offset = dest_offset_bits / 8;
e1d87d
-
e1d87d
-      /* Check whether the data can be transferred byte-wise.  */
e1d87d
-      if (dest_offset_bits % 8 == 0 && source_offset_bits % 8 == 0
e1d87d
-	  && this_size_bits % 8 == 0)
e1d87d
-	{
e1d87d
-	  source_buffer = contents + source_offset;
e1d87d
-	  need_bitwise = 0;
e1d87d
-	}
e1d87d
-      else
e1d87d
-	{
e1d87d
-	  buffer.reserve (this_size);
e1d87d
-	  source_buffer = buffer.data ();
e1d87d
-	  need_bitwise = 1;
e1d87d
-	}
e1d87d
-
e1d87d
       switch (p->location)
e1d87d
 	{
e1d87d
 	case DWARF_VALUE_REGISTER:
e1d87d
@@ -2047,21 +2022,44 @@ write_pieced_value (struct value *to, struct value *from)
e1d87d
 	  }
e1d87d
 	  break;
e1d87d
 	case DWARF_VALUE_MEMORY:
e1d87d
-	  if (need_bitwise)
e1d87d
-	    {
e1d87d
-	      /* Only the first and last bytes can possibly have any
e1d87d
-		 bits reused.  */
e1d87d
-	      read_memory (p->v.mem.addr + dest_offset, buffer.data (), 1);
e1d87d
-	      read_memory (p->v.mem.addr + dest_offset + this_size - 1,
e1d87d
-			   &buffer[this_size - 1], 1);
e1d87d
-	      copy_bitwise (buffer.data (), dest_offset_bits % 8,
e1d87d
-			    contents, source_offset_bits,
e1d87d
-			    this_size_bits,
e1d87d
-			    bits_big_endian);
e1d87d
-	    }
e1d87d
+	  {
e1d87d
+	    CORE_ADDR start_addr = p->v.mem.addr + dest_offset_bits / 8;
e1d87d
+
e1d87d
+	    if (dest_offset_bits % 8 == 0 && this_size_bits % 8 == 0
e1d87d
+		&& source_offset_bits % 8 == 0)
e1d87d
+	      {
e1d87d
+		/* Everything is byte-aligned; no buffer needed.  */
e1d87d
+		write_memory (start_addr,
e1d87d
+			      contents + source_offset_bits / 8,
e1d87d
+			      this_size_bits / 8);
e1d87d
+		break;
e1d87d
+	      }
e1d87d
+
e1d87d
+	    this_size = bits_to_bytes (dest_offset_bits, this_size_bits);
e1d87d
+	    buffer.reserve (this_size);
e1d87d
 
e1d87d
-	  write_memory (p->v.mem.addr + dest_offset,
e1d87d
-			source_buffer, this_size);
e1d87d
+	    if (dest_offset_bits % 8 != 0 || this_size_bits % 8 != 0)
e1d87d
+	      {
e1d87d
+		if (this_size <= 8)
e1d87d
+		  {
e1d87d
+		    /* Perform a single read for small sizes.  */
e1d87d
+		    read_memory (start_addr, buffer.data (), this_size);
e1d87d
+		  }
e1d87d
+		else
e1d87d
+		  {
e1d87d
+		    /* Only the first and last bytes can possibly have any
e1d87d
+		       bits reused.  */
e1d87d
+		    read_memory (start_addr, buffer.data (), 1);
e1d87d
+		    read_memory (start_addr + this_size - 1,
e1d87d
+				 &buffer[this_size - 1], 1);
e1d87d
+		  }
e1d87d
+	      }
e1d87d
+
e1d87d
+	    copy_bitwise (buffer.data (), dest_offset_bits % 8,
e1d87d
+			  contents, source_offset_bits,
e1d87d
+			  this_size_bits, bits_big_endian);
e1d87d
+	    write_memory (start_addr, buffer.data (), this_size);
e1d87d
+	  }
e1d87d
 	  break;
e1d87d
 	default:
e1d87d
 	  mark_value_bytes_optimized_out (to, 0, TYPE_LENGTH (value_type (to)));