toplev.c (init_asm_output): Add explicit 'b' to mode when opening asm_out_file.
authorDanny Smith <dannysmith@users.sourceforge.net>
Sat, 5 Jun 2004 07:28:27 +0000 (07:28 +0000)
committerDanny Smith <dannysmith@gcc.gnu.org>
Sat, 5 Jun 2004 07:28:27 +0000 (07:28 +0000)
        * toplev.c (init_asm_output): Add explicit 'b' to mode when
        opening asm_out_file.
        * c-pch.c (c_common_write_pch): Remove unnecessary fflush before
        reading asm_out_file. Replace fflush after reading asm_out_file
        with fseek.
        * hosthooks-def.h (HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY): Define
        default and add to HOST_HOOKS_INITIALIZER.
        * hosthooks.h (gt_pch_alloc_granularity): Declare hook function.
        * ggc-common.c (default_gt_pch_alloc_granularity): New function.
        (gt_pch_save): Use host_hooks.gt_pch_alloc_granularity
        to set mmi.offset padding.
         * config.gcc (i[34567]86-*-mingw32*): Set target_gtfiles to
        $(srcdir)/config/i386/winnt.c.
        (i[34567]86-*-pe | i[34567]86-*-cygwin*): Likewise.
        (i[34567]86-*-uwin*): Likewise.
        *i[34567]86-*-interix3*): Likewise.
        * config.host (i[34567]86-*-mingw32*): Set out_host_hook_obj.
        * config/i386/host-mingw32.c: New file.
        * config/i386/x-mingw32: Add rule for host-mingw32.o.
        * config/i386/winnt.c: (struct extern_list) Tag as GTY.
        (extern_head): Likewise.
        (struct export_list) Likewise.
        (export_head): Likewise.
        (i386_pe_record_external_function): Use ggc_alloc.
        (i386_pe_record_exported_symbol): Likewise.
        Include "gt-winnt.h" at end.
        * doc/hostconfig.texi: Document
HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY.

From-SVN: r82643

12 files changed:
gcc/ChangeLog
gcc/c-pch.c
gcc/config.gcc
gcc/config.host
gcc/config/i386/host-mingw32.c [new file with mode: 0644]
gcc/config/i386/winnt.c
gcc/config/i386/x-mingw32
gcc/doc/hostconfig.texi
gcc/ggc-common.c
gcc/hosthooks-def.h
gcc/hosthooks.h
gcc/toplev.c

index 28e486ccccbdc2bba625a897c801ef27809bb9c9..4b1360aeec3315aeefef9244ffed7a6db902e70f 100644 (file)
@@ -1,3 +1,34 @@
+2004-06-05  Danny Smith  <dannysmith@users.sourceforge.net>
+
+        * toplev.c (init_asm_output): Add explicit 'b' to mode when
+        opening asm_out_file. 
+        * c-pch.c (c_common_write_pch): Remove unnecessary fflush before
+        reading asm_out_file. Replace fflush after reading asm_out_file
+        with fseek.
+        * hosthooks-def.h (HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY): Define
+        default and add to HOST_HOOKS_INITIALIZER. 
+        * hosthooks.h (gt_pch_alloc_granularity): Declare hook function.
+        * ggc-common.c (default_gt_pch_alloc_granularity): New function.
+        (gt_pch_save): Use host_hooks.gt_pch_alloc_granularity 
+        to set mmi.offset padding.
+         * config.gcc (i[34567]86-*-mingw32*): Set target_gtfiles to
+        $(srcdir)/config/i386/winnt.c.
+        (i[34567]86-*-pe | i[34567]86-*-cygwin*): Likewise.
+        (i[34567]86-*-uwin*): Likewise.
+        *i[34567]86-*-interix3*): Likewise.
+        * config.host (i[34567]86-*-mingw32*): Set out_host_hook_obj.
+        * config/i386/host-mingw32.c: New file.
+        * config/i386/x-mingw32: Add rule for host-mingw32.o.
+        * config/i386/winnt.c: (struct extern_list) Tag as GTY.
+        (extern_head): Likewise.
+        (struct export_list) Likewise.
+        (export_head): Likewise.
+        (i386_pe_record_external_function): Use ggc_alloc.
+        (i386_pe_record_exported_symbol): Likewise.
+        Include "gt-winnt.h" at end.
+        * doc/hostconfig.texi: Document
+       HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY.
+
 2004-06-04  Bernardo Innocenti  <bernie@develer.com>
 
        * config/m68k/m68k.h: Remove comments copied over from tm.texi.
index 8e2e6f126fa3c4a9f7fc76517e5fb03816627790..03cf3bf08bcae4379cedfd1c4fb2ddb65e8e5a90 100644 (file)
@@ -194,7 +194,6 @@ c_common_write_pch (void)
     fatal_error ("can't write %s: %m", pch_file);
   
   buf = xmalloc (16384);
-  fflush (asm_out_file);
 
   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
     fatal_error ("can't seek in %s: %m", asm_file_name);
@@ -211,8 +210,10 @@ c_common_write_pch (void)
       written += size;
     }
   free (buf);
-  /* asm_out_file can be written afterwards, so must be flushed first.  */
-  fflush (asm_out_file);
+  /* asm_out_file can be written afterwards, so fseek to clear
+     _IOREAD flag.  */
+  if (fseek (asm_out_file, 0, SEEK_END) != 0)
+    fatal_error ("can't seek in %s: %m", asm_file_name);
 
   gt_pch_save (pch_outfile);
   cpp_write_pch_state (parse_in, pch_outfile);
index 67efab57f15a4d0948d7d5746236fdc21158743d..8bf7d0eb85e06ce5b96b8d07087d2eba0a4175fe 100644 (file)
@@ -1035,6 +1035,7 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*)
        tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/cygwin.h"
        xm_file=i386/xm-cygwin.h
        tmake_file="i386/t-cygwin i386/t-cygming"
+       target_gtfiles="\$(srcdir)/config/i386/winnt.c"
        extra_objs=winnt.o
        c_target_objs=cygwin2.o
        cxx_target_objs=cygwin2.o
@@ -1047,6 +1048,7 @@ i[34567]86-*-mingw32*)
        tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
        xm_file=i386/xm-mingw32.h
        tmake_file="i386/t-cygming i386/t-mingw32"
+       target_gtfiles="\$(srcdir)/config/i386/winnt.c"
        extra_objs=winnt.o
        if test x$enable_threads = xyes; then
                thread_file='win32'
@@ -1063,6 +1065,7 @@ i[34567]86-*-uwin*)
        tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygwin.h i386/uwin.h"
        tmake_file="i386/t-cygwin i386/t-uwin"
        extra_objs=winnt.o
+       target_gtfiles="\$(srcdir)/config/i386/winnt.c"
        if test x$enable_threads = xyes; then
                thread_file='win32'
        fi
@@ -1072,6 +1075,7 @@ i[34567]86-*-interix3*)
        tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
        tmake_file="i386/t-interix"
        extra_objs=winnt.o
+       target_gtfiles="\$(srcdir)/config/i386/winnt.c"
        if test x$enable_threads = xyes ; then
                thread_file='posix'
        fi
index 9734966e604afc842c3bc7dfade806480c519b6c..67a067c169ffe9ebc17f633fd49c887c6de51f73 100644 (file)
@@ -143,6 +143,7 @@ case ${host} in
     host_xmake_file=i386/x-mingw32
     host_exeext=.exe
     host_can_use_collect2=no
+    out_host_hook_obj=host-mingw32.o
     ;;
   i[34567]86-*-uwin*)
     echo "*** UWIN may not be used as a host platform because"
diff --git a/gcc/config/i386/host-mingw32.c b/gcc/config/i386/host-mingw32.c
new file mode 100644 (file)
index 0000000..0e3fdd7
--- /dev/null
@@ -0,0 +1,148 @@
+/* mingw32 host-specific hook definitions.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+#include "toplev.h"
+#include "diagnostic.h"
+
+
+#define WIN32_LEAN_AND_MEAN  /* Not so important if we have windows.h.gch.  */
+#include <windows.h>
+
+static void * mingw32_gt_pch_get_address (size_t, int);
+static int mingw32_gt_pch_use_address (void *, size_t, int, size_t);
+static size_t mingw32_gt_pch_alloc_granularity (void);
+
+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address
+#undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY
+#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity
+
+static inline void w32_error(const char*, const char*, int, const char*);
+
+/* FIXME: Is this big enough?  */
+static const size_t pch_VA_max_size  = 128 * 1024 * 1024;
+
+/* Granularity for reserving address space.  */
+static const size_t va_granularity = 0x10000;
+
+/* Print out the GetLastError() translation.  */ 
+static inline void
+w32_error (const char* function, const char* file, int line,
+          const char* my_msg)
+{
+  LPSTR w32_msgbuf;
+  FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER
+                 | FORMAT_MESSAGE_FROM_SYSTEM
+                 | FORMAT_MESSAGE_IGNORE_INSERTS
+                 | FORMAT_MESSAGE_MAX_WIDTH_MASK,
+                 NULL, GetLastError(),
+                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                 (LPSTR) &w32_msgbuf, 0, NULL);
+  fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n",
+         function, trim_filename (file), line, my_msg, w32_msgbuf);
+  LocalFree ((HLOCAL)w32_msgbuf);
+}
+
+/* Granularity for reserving address space.  */
+static size_t mingw32_gt_pch_alloc_granularity (void)
+{
+  return va_granularity;
+}
+
+/* Identify an address that's likely to be free in a subsequent invocation
+   of the compiler.  The area should be able to hold SIZE bytes.  FD is an
+   open file descriptor if the host would like to probe with mmap.  */
+
+static void *
+mingw32_gt_pch_get_address (size_t size, int fd  ATTRIBUTE_UNUSED)
+{
+  void* res;
+  size = (size + va_granularity - 1) & ~(va_granularity - 1);
+  if (size > pch_VA_max_size)
+    return NULL;
+
+  /* FIXME: We let system determine base by setting first arg to NULL.
+     Allocating at top of available address space avoids unnecessary
+     fragmentation of "ordinary" (malloc's)  address space but may not be safe
+     with delayed load of system dll's. Preferred addresses for NT system
+     dlls is in 0x70000000 to 0x78000000 range.
+     If we allocate at bottom we need to reserve the address as early as possible
+     and at the same point in each invocation. */
+  res = VirtualAlloc (NULL, pch_VA_max_size,
+                     MEM_RESERVE | MEM_TOP_DOWN,
+                     PAGE_NOACCESS);
+  if (!res)
+    w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
+  else
+    /* We do not need the address space for now, so free it.  */
+    VirtualFree (res, 0, MEM_RELEASE);
+
+  return res; 
+}
+
+/* ADDR is an address returned by gt_pch_get_address.  Attempt to allocate
+   SIZE bytes at the same address and load it with the data from FD at 
+   OFFSET.  Return -1 if we couldn't allocate memory at ADDR, return 0
+   if the memory is allocated but the data not loaded, return 1 if done.  */
+
+static int
+mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
+                           size_t offset)
+{
+  void * mmap_addr;
+  static HANDLE mmap_handle;
+
+  if (size == 0)
+    return 0;
+  
+  /* Offset must be also be a multiple of allocation granularity for
+     this to work.  We can't change the offset. */ 
+  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
+    return -1;
+
+  mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd),
+                                  NULL, PAGE_WRITECOPY | SEC_COMMIT,
+                                  0, 0,  NULL);
+  if (mmap_handle == NULL)
+    {
+      w32_error (__FUNCTION__,  __FILE__, __LINE__, "CreateFileMapping");
+      return -1; 
+    }
+  mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
+                              size, addr);
+  if (mmap_addr != addr)
+    {
+      w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
+      CloseHandle(mmap_handle);
+      return  -1;
+    }
+
+  return 1;
+}
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
index 6196d32aa6f21f4a20a35831bee71439ad472689..0b51aa420708d8100a9f1fa29dbf726f28b4417c 100644 (file)
@@ -769,13 +769,13 @@ i386_pe_declare_function_type (FILE *file, const char *name, int public)
 
 /* Keep a list of external functions.  */
 
-struct extern_list
+struct extern_list GTY(())
 {
   struct extern_list *next;
   const char *name;
 };
 
-static struct extern_list *extern_head;
+static GTY(()) struct extern_list *extern_head;
 
 /* Assemble an external function reference.  We need to keep a list of
    these, so that we can output the function types at the end of the
@@ -788,7 +788,7 @@ i386_pe_record_external_function (const char *name)
 {
   struct extern_list *p;
 
-  p = (struct extern_list *) xmalloc (sizeof *p);
+  p = (struct extern_list *) ggc_alloc (sizeof *p);
   p->next = extern_head;
   p->name = name;
   extern_head = p;
@@ -796,14 +796,14 @@ i386_pe_record_external_function (const char *name)
 
 /* Keep a list of exported symbols.  */
 
-struct export_list
+struct export_list GTY(())
 {
   struct export_list *next;
   const char *name;
   int is_data;         /* used to type tag exported symbols.  */
 };
 
-static struct export_list *export_head;
+static GTY(()) struct export_list *export_head;
 
 /* Assemble an export symbol entry.  We need to keep a list of
    these, so that we can output the export list at the end of the
@@ -816,7 +816,7 @@ i386_pe_record_exported_symbol (const char *name, int is_data)
 {
   struct export_list *p;
 
-  p = (struct export_list *) xmalloc (sizeof *p);
+  p = (struct export_list *) ggc_alloc (sizeof *p);
   p->next = export_head;
   p->name = name;
   p->is_data = is_data;
@@ -861,3 +861,5 @@ i386_pe_file_end (void)
        }
     }
 }
+
+#include "gt-winnt.h"
index 04593aa727fd0d856654381f4256cc193c661081..8b6a98565ef82a137908b69b525920957cd42e58 100644 (file)
@@ -2,3 +2,8 @@
 # Make local_includedir relative to EXEC_PREFIX 
 #
 local_includedir=$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include
+
+host-mingw32.o : $(srcdir)/config/i386/host-mingw32.c $(CONFIG_H) $(SYSTEM_H) \
+  coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+               $(srcdir)/config/i386/host-mingw32.c
index c97b41b7c2ecd5d1ef2af9887c7e683acf3e7881..a016e561777ee00225dcf04b9879fcc5b213bef7 100644 (file)
@@ -71,6 +71,13 @@ indicate an out-of-date PCH file (built by some other GCC executable),
 and such a PCH file won't work.
 @end deftypefn
 
+@deftypefn {Host Hook} size_t HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY (void);
+This host hook returns the alignment required for allocating virtual
+memory. Usually this is the same as getpagesize, but on some hosts the
+alignment for reserving memory differs from the pagesize for committing
+memory.
+@end deftypefn
+
 @node Filesystem
 @section Host Filesystem
 @cindex configuration file
index 4939cb6988886ed9ef870ada95a1305caad68e07..cc0dc93be84177b531ffa64699980d571f83a927 100644 (file)
@@ -431,7 +431,7 @@ gt_pch_save (FILE *f)
   char *this_object = NULL;
   size_t this_object_size = 0;
   struct mmap_info mmi;
-  size_t page_size = getpagesize();
+  const size_t mmap_offset_alignment = host_hooks.gt_pch_alloc_granularity();
 
   gt_pch_save_stringpool ();
 
@@ -481,14 +481,15 @@ gt_pch_save (FILE *f)
 
   ggc_pch_prepare_write (state.d, state.f);
 
-  /* Pad the PCH file so that the mmapped area starts on a page boundary.  */
+  /* Pad the PCH file so that the mmapped area starts on an allocation
+     granularity (usually page) boundary.  */
   {
     long o;
     o = ftell (state.f) + sizeof (mmi);
     if (o == -1)
       fatal_error ("can't get position in PCH file: %m");
-    mmi.offset = page_size - o % page_size;
-    if (mmi.offset == page_size)
+    mmi.offset = mmap_offset_alignment - o % mmap_offset_alignment;
+    if (mmi.offset == mmap_offset_alignment)
       mmi.offset = 0;
     mmi.offset += o;
   }
@@ -612,6 +613,16 @@ default_gt_pch_use_address (void *base, size_t size, int fd ATTRIBUTE_UNUSED,
   return (addr == base) - 1;
 }
 
+/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS.   Return the
+   alignment required for allocating virtual memory. Usually this is the
+   same as pagesize.  */
+
+size_t
+default_gt_pch_alloc_granularity (void)
+{
+  return getpagesize();
+}
+
 #if HAVE_MMAP_FILE
 /* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is present.
    We temporarily allocate SIZE bytes, and let the kernel place the data
index 81761f9f1381b24b923f72b3ee4e3cf5c5fad4c7..910f7830ec74f7a6a4af7ddb3316919fdec4f6bf 100644 (file)
@@ -32,8 +32,12 @@ Boston, MA 02111-1307, USA.  */
 #define HOST_HOOKS_GT_PCH_USE_ADDRESS default_gt_pch_use_address
 #endif
 
+#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY \
+  default_gt_pch_alloc_granularity
+
 extern void* default_gt_pch_get_address (size_t, int);
 extern int default_gt_pch_use_address (void *, size_t, int, size_t);
+extern size_t default_gt_pch_alloc_granularity (void);
 extern void* mmap_gt_pch_get_address (size_t, int);
 extern int mmap_gt_pch_use_address (void *, size_t, int, size_t);
 
@@ -41,7 +45,8 @@ extern int mmap_gt_pch_use_address (void *, size_t, int, size_t);
 #define HOST_HOOKS_INITIALIZER {               \
   HOST_HOOKS_EXTRA_SIGNALS,                    \
   HOST_HOOKS_GT_PCH_GET_ADDRESS,               \
-  HOST_HOOKS_GT_PCH_USE_ADDRESS                        \
+  HOST_HOOKS_GT_PCH_USE_ADDRESS,               \
+  HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY          \
 }
 
 #endif /* GCC_HOST_HOOKS_DEF_H */
index c8b7c0fbac7634093f0248e17ea8bbb9b713bb25..0ac89f5e7c75fd1a6e679b52a60509c86c6e3e4f 100644 (file)
@@ -36,6 +36,10 @@ struct host_hooks
      if the memory is allocated but the data not loaded, return 1 if done.  */
   int (*gt_pch_use_address) (void *addr, size_t size, int fd, size_t offset);
 
+  /*  Return the alignment required for allocating virtual memory. Usually
+      this is the same as pagesize.  */
+  size_t (*gt_pch_alloc_granularity) (void);
+
   /* Whenever you add entries here, make sure you adjust hosthooks-def.h.  */
 };
 
index afbdb5cf9faf808629c17665e5e8ef3eacf52c09..2741be5047fd8d169caced4dd84911eda80ee95a 100644 (file)
@@ -2039,7 +2039,7 @@ init_asm_output (const char *name)
       if (!strcmp (asm_file_name, "-"))
        asm_out_file = stdout;
       else
-       asm_out_file = fopen (asm_file_name, "w+");
+       asm_out_file = fopen (asm_file_name, "w+b");
       if (asm_out_file == 0)
        fatal_error ("can't open %s for writing: %m", asm_file_name);
     }