This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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]

Re: [PATCH 2/5] support: don't pass to resolv_test_start a big struct by value




On Пн, Mar 25, 2019 at 13:35:56, Florian Weimer <fw@deneb.enyo.de> wrote:
* Konstantin Kharlamov:

 On Пн, Mar 25, 2019 at 11:33:28, Florian Weimer <fw@deneb.enyo.de>
 wrote:
 * Konstantin Kharlamov:

  diff --git a/support/resolv_test.h b/support/resolv_test.h
  index c9e48205ab..880330ad5c 100644
  --- a/support/resolv_test.h
  +++ b/support/resolv_test.h
  @@ -116,7 +116,7 @@ void resolv_test_init (void);
      needed.  As a side effect, NSS is reconfigured to use nss_dns
 only
      for aplicable databases, and the process may enter a network
      namespace for better isolation.  */
  -struct resolv_test *resolv_test_start (struct
 resolv_redirect_config);
  +struct resolv_test *resolv_test_start (const struct
 resolv_redirect_config*);

This patch would adjusting all the tests that call resolv_test_start, and these changes are missing from the patch. It is unclear how this
 change would be an improvement because most tests call
resolv_test_start exactly once and the parameter object is never used again. Passing a pointer requires writing the argument object to the stack *and* supplying its address to resolv_test_start, which requires
 more work.  (Maybe some targets have more optimized code for struct
 initialization than passing many zero arguments, but that's a GCC
 issue which will eventually be fixed.)

Wow, are you saying that in the assembly the address that gets passed to resolve_test_start() would be not the address of struct, but instead an address of an addres on a stack that is an address of the struct…?

With the pointer-to-struct argument, you need to write the temporary
object to the stack and pass its address.

With the struct argument, you need to write the temporary object to
the stack, in the form of an argument list.

The second case avoids computing and passing the address of the
temporary object.

Can't reproduce here. Testcase:

   $ cat test.c
   #include <stdlib.h>

   struct Foo {
       int a;
       char b;
   };

   void get_foo(struct Foo*);

   int main() {
       struct Foo foo = {};
       get_foo(&foo);
   }
   $ gcc test.c -S -fverbose-asm -o a.S -g3 -O0

Produces the following code for main() in a.S file (snip of a relevant part):

       .globl	main
       .type	main, @function
   main:
   .LFB6:
       .file 1 "test.c"
       .loc 1 10 12
       .cfi_startproc
       pushq	%rbp	#
       .cfi_def_cfa_offset 16
       .cfi_offset 6, -16
       movq	%rsp, %rbp	#,
       .cfi_def_cfa_register 6
       subq	$16, %rsp	#,
   # test.c:10: int main() {
       .loc 1 10 12
movq %fs:40, %rax # MEM[(<address-space-1> long unsigned int *)40B], tmp91
       movq	%rax, -8(%rbp)	# tmp91, D.2539
       xorl	%eax, %eax	# tmp91
   # test.c:11:     struct Foo foo = {};
       .loc 1 11 16
       movq	$0, -16(%rbp)	#, foo
   # test.c:12:     get_foo(&foo);
       .loc 1 12 5
       leaq	-16(%rbp), %rax	#, tmp89
       movq	%rax, %rdi	# tmp89,
       call	get_foo@PLT	#
       movl	$0, %eax	#, _5
   # test.c:13: }

The 3 actions being done just before get_foo(), commented:

       leaq	-16(%rbp), %rax	# put address of the struct to rax register
movq %rax, %rdi # move content of rax into rdi (for whatever reason)
       call	get_foo@PLT     # call the function

Note, it doesn't put the address into stack, it passes it in registers, just as I'd expect.



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