This is the mail archive of the egcs@egcs.cygnus.com mailing list for the EGCS project. See the EGCS home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: #pragma interface



| > > With #pragma       86 s                 1649639 bytes
| > > Without #pragma    86 s                 1663340 bytes
| > 
| > Thanks for the information.  It'd be nice to track down these random
| > few bytes that were not squeezed out
| 
| One source certainly is garbage exception regions. If we have linkonce
| functions, they get slots in .gcc_except_table, and .eh_frame. Once
| duplicate code is removed, the duplicate slots stay. I don't know
| whether this would accound for the 14K; having a section-by-section
| comparison would be helpful.
| 
| Regards,
| Martin

I compile(d) with -fno-exceptions

In an attempt to provide more info, I did remove the "#pragma interface"
every time from exactly ONE header file, and then printed the sizes
of the sections.  The result of that is:

                                  removed #pragma interface
   text    data     bss   total	  from header file:
 354556   10404    3920  368880   sys.h
 353930   10404    3920  368254   demangle.h
 353506   10416    3920  367842   debug.h
 353466   10404    3920  367790   support.h
 353431   10388    3920  367739   debugmalloc.h
 353115   10372    3920  367407   sbll.h
 353019   10404    3920  367343   signals.h
 352927   10404    3920  367251   char2str.h
 352860   10404    3920  367184   buf2str.h
 352773   10404    3920  367097   libr_app.h
 352722   10372    3920  367014   file.h
 352681   10400    3920  367001   dbstreambuf.h
 352676   10404    3920  367000   inet_support.h
 352551   10404    3920  366875   ostream_operators.h
 352490   10404    3920  366814   lockable_auto_ptr.h
 352481   10404    3920  366805   strerrno.h
 352426   10404    3920  366750    -
 352423   10436    3920  366779   llists_crosslink.h
 352388   10404    3920  366712   ffstl.h
 352381   10404    3920  366705   ecbll.h
 352380   10404    3920  366704   bcd2str.h
 352085   10396    3912  366393   ebll.h
 351891   10404    3920  366215   pipe.h
 350215   10340    3908  364463   cbll.h
 348322   10272    3896  362490   expire.h
 347828   10292    3904  362024   crosslink.h
 346193   10156    3864  360213   execve.h

From some header files, it was already removed.
So I added it instead:

                                  added #pragma interface
   text    data     bss   total	  to header file:
 351515   10404    3920  365839   select.h
 351786   10404    3920  366110   iodbbuf_fd.h
 352362   10404    3920  366686   listen_sock.h
 352362   10404    3920  366686   listen_sock_dtct.h
 352426   10404    3920  366750    -
 353303   10436    3920  367659   sock.h
 354257   10464    3928  368649   events.h
 355505   10488    3940  369933   timing.h
 361015   11296    4048  376359   traits.h

Interesting is that the size *grows* 3% by *adding* a "#pragma interface"
just to traits.h :)...

The bad cases however are at the top: The cases in which adding
"#pragma interface" indeed makes the (text) size shrink.

I'd charaterize these "winners" as the ones that are included in the
most source files and/or contain functions that are used the most often.
There is no reason to assume they do something special, except being
used a lot.

"sys.h" for instance is #included in EVERY source file, before ANY
other header file is included (including system header files).

A test file with only '#include "libr/sys.h"' in it, compiled
with -E, and skipping all empty lines and comments gives:

==============================================================================
extern "C" { 
typedef unsigned char __u_char;
typedef unsigned short __u_short;
typedef unsigned int __u_int;
typedef unsigned long __u_long;
typedef unsigned long long int __u_quad_t;
typedef long long int __quad_t;
typedef __quad_t *__qaddr_t;
typedef __u_quad_t __dev_t;		 
typedef __u_int __uid_t;		 
typedef __u_int __gid_t;		 
typedef __u_long __ino_t;		 
typedef __u_int __mode_t;		 
typedef __u_int __nlink_t; 		 
typedef long int __off_t;		 
typedef __quad_t __loff_t;		 
typedef int __pid_t;			 
typedef int __ssize_t;			 
typedef struct
  {
    int __val[2];
  } __fsid_t;				 
typedef int __daddr_t;			 
typedef char *__caddr_t;
typedef long int __time_t;
typedef long int __swblk_t;		 

typedef long int __clock_t;
typedef unsigned long int __fd_mask;
typedef struct
  {
    __fd_mask fds_bits[1024  / (8 * sizeof (__fd_mask)) ];
  } __fd_set;
typedef int __key_t;
typedef unsigned short int __ipc_pid_t;
typedef __u_char u_char;
typedef __u_short u_short;
typedef __u_int u_int;
typedef __u_long u_long;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;
typedef __fsid_t fsid_t;
typedef __dev_t dev_t;
typedef __gid_t gid_t;
typedef __ino_t ino_t;
typedef __mode_t mode_t;
typedef __nlink_t nlink_t;
typedef __off_t off_t;
typedef __loff_t loff_t;
typedef __pid_t pid_t;
typedef __uid_t uid_t;
typedef __ssize_t ssize_t;
typedef __daddr_t daddr_t;
typedef __caddr_t caddr_t;
typedef __key_t key_t;
typedef __time_t time_t;
typedef unsigned int size_t;
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
typedef int int8_t __attribute__ ((__mode__ (  __QI__ ))) ;
typedef unsigned int u_int8_t __attribute__ ((__mode__ (  __QI__ ))) ;
typedef int int16_t __attribute__ ((__mode__ (  __HI__ ))) ;
typedef unsigned int u_int16_t __attribute__ ((__mode__ (  __HI__ ))) ;
typedef int int32_t __attribute__ ((__mode__ (  __SI__ ))) ;
typedef unsigned int u_int32_t __attribute__ ((__mode__ (  __SI__ ))) ;
typedef int int64_t __attribute__ ((__mode__ (  __DI__ ))) ;
typedef unsigned int u_int64_t __attribute__ ((__mode__ (  __DI__ ))) ;
typedef int register_t __attribute__ ((__mode__ (__word__)));
struct timespec
  {
    long int tv_sec;		 
    long int tv_nsec;		 
  };
extern "C" { 
struct timeval;
typedef __fd_mask fd_mask;
typedef __fd_set fd_set;
extern int __select  (int __nfds, __fd_set *__readfds,
			  __fd_set *__writefds, __fd_set *__exceptfds,
			  struct timeval *__timeout)  ;
extern int select  (int __nfds, __fd_set *__readfds,
			__fd_set *__writefds, __fd_set *__exceptfds,
			struct timeval *__timeout)  ;
extern int __pselect  (int __nfds, __fd_set *__readfds,
			   __fd_set *__writefds, __fd_set *__exceptfds,
			   struct timespec *__timeout)  ;
extern int pselect  (int __nfds, __fd_set *__readfds,
			 __fd_set *__writefds, __fd_set *__exceptfds,
			 struct timespec *__timeout)  ;
} 
} 
const unsigned int malloc_overhead_c = 0;
typedef int sa_handler_param_type;
static const char rcs_ident_sys_sys_h[] __attribute__ ((unused)) =   "$Id: sys.h,v 1.1.1.1 1998/06/17 16:02:19 carlo Exp $" ; 
==============================================================================

So, a clue could perhaps be that a `typedef' uses space in the text segment?
(In a duplicating way)

Note that all of these typedefs come from system header files that were
included from sys.h.  It surprices me that "#pragma interface" seems to
have influence in this case.  Perhaps I should start to include all my
system headers from own headers, so I can add a "#pragma interface" in
front of it (the system headers do not contain a "#pragma interface" by
themselfs).

If I can provide any other info, please let me know.
Hopefully things get easier once I can release libr (I am waiting for
Qt-2.0 to be released because I want to use its QPL).

After adding "#pragma interface" only in those header files where it
makes the text segment shrink, I could get it as small as:

   text    data     bss     dec     hex filename
 329351    9680    3780  342811   53b1b ../../lib/libr.so.0.2.5

which is 10% smaller than the worsed case...

Regard,

 Carlo Wood  <carlo@runaway.xs4all.nl>