aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/dyn_load.c
diff options
context:
space:
mode:
authorBryce McKinlay <bryce@gcc.gnu.org>2004-08-12 21:14:30 +0000
committerBryce McKinlay <bryce@gcc.gnu.org>2004-08-12 21:14:30 +0000
commit4e638f718c43d7525f7d833b52e9702e5b6dc0ed (patch)
treec6eada4017a3d213b1edf5cb23b7883ac3035290 /boehm-gc/dyn_load.c
parentb59596cbb42f36d72f2b91755464eac6826e0b43 (diff)
Import GC 6.3
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/boehm@85899 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'boehm-gc/dyn_load.c')
-rw-r--r--boehm-gc/dyn_load.c113
1 files changed, 108 insertions, 5 deletions
diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
index 162f7dcb124..9bd9e060688 100644
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -91,10 +91,18 @@
/* Newer versions of GNU/Linux define this macro. We
* define it similarly for any ELF systems that don't. */
# ifndef ElfW
-# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32
-# define ElfW(type) Elf32_##type
+# ifdef __NetBSD__
+# if ELFSIZE == 32
+# define ElfW(type) Elf32_##type
+# else
+# define ElfW(type) Elf64_##type
+# endif
# else
-# define ElfW(type) Elf64_##type
+# if !defined(ELF_CLASS) || ELF_CLASS == ELFCLASS32
+# define ElfW(type) Elf32_##type
+# else
+# define ElfW(type) Elf64_##type
+# endif
# endif
# endif
@@ -727,6 +735,90 @@ void GC_register_dynamic_libraries()
# define HAVE_REGISTER_MAIN_STATIC_DATA
+ GC_bool GC_warn_fb = TRUE; /* Warn about traced likely */
+ /* graphics memory. */
+ GC_bool GC_disallow_ignore_fb = FALSE;
+ int GC_ignore_fb_mb; /* Ignore mappings bigger than the */
+ /* specified number of MB. */
+ GC_bool GC_ignore_fb = FALSE; /* Enable frame buffer */
+ /* checking. */
+
+ /* Issue warning if tracing apparent framebuffer. */
+ /* This limits us to one warning, and it's a back door to */
+ /* disable that. */
+
+ /* Should [start, start+len) be treated as a frame buffer */
+ /* and ignored? */
+ /* Unfortunately, we currently have no real way to tell */
+ /* automatically, and rely largely on user input. */
+ /* FIXME: If we had more data on this phenomenon (e.g. */
+ /* is start aligned to a MB multiple?) we should be able to */
+ /* do better. */
+ /* Based on a very limited sample, it appears that: */
+ /* - Frame buffer mappings appear as mappings of length */
+ /* 2**n MB - 192K. (We guess the 192K can vary a bit.) */
+ /* - Have a stating address at best 64K aligned. */
+ /* I'd love more information about the mapping, since I */
+ /* can't reproduce the problem. */
+ static GC_bool is_frame_buffer(ptr_t start, size_t len)
+ {
+ static GC_bool initialized = FALSE;
+# define MB (1024*1024)
+# define DEFAULT_FB_MB 15
+# define MIN_FB_MB 3
+
+ if (GC_disallow_ignore_fb) return FALSE;
+ if (!initialized) {
+ char * ignore_fb_string = GETENV("GC_IGNORE_FB");
+
+ if (0 != ignore_fb_string) {
+ while (*ignore_fb_string == ' ' || *ignore_fb_string == '\t')
+ ++ignore_fb_string;
+ if (*ignore_fb_string == '\0') {
+ GC_ignore_fb_mb = DEFAULT_FB_MB;
+ } else {
+ GC_ignore_fb_mb = atoi(ignore_fb_string);
+ if (GC_ignore_fb_mb < MIN_FB_MB) {
+ WARN("Bad GC_IGNORE_FB value. Using %ld\n", DEFAULT_FB_MB);
+ GC_ignore_fb_mb = DEFAULT_FB_MB;
+ }
+ }
+ GC_ignore_fb = TRUE;
+ } else {
+ GC_ignore_fb_mb = DEFAULT_FB_MB; /* For warning */
+ }
+ initialized = TRUE;
+ }
+ if (len >= ((size_t)GC_ignore_fb_mb << 20)) {
+ if (GC_ignore_fb) {
+ return TRUE;
+ } else {
+ if (GC_warn_fb) {
+ WARN("Possible frame buffer mapping at 0x%lx: \n"
+ "\tConsider setting GC_IGNORE_FB to improve performance.\n",
+ start);
+ GC_warn_fb = FALSE;
+ }
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+ }
+
+# ifdef DEBUG_VIRTUALQUERY
+ void GC_dump_meminfo(MEMORY_BASIC_INFORMATION *buf)
+ {
+ GC_printf4("BaseAddress = %lx, AllocationBase = %lx, RegionSize = %lx(%lu)\n",
+ buf -> BaseAddress, buf -> AllocationBase, buf -> RegionSize,
+ buf -> RegionSize);
+ GC_printf4("\tAllocationProtect = %lx, State = %lx, Protect = %lx, "
+ "Type = %lx\n",
+ buf -> AllocationProtect, buf -> State, buf -> Protect,
+ buf -> Type);
+ }
+# endif /* DEBUG_VIRTUALQUERY */
+
void GC_register_dynamic_libraries()
{
MEMORY_BASIC_INFORMATION buf;
@@ -763,7 +855,11 @@ void GC_register_dynamic_libraries()
if (buf.State == MEM_COMMIT
&& (protect == PAGE_EXECUTE_READWRITE
|| protect == PAGE_READWRITE)
- && !GC_is_heap_base(buf.AllocationBase)) {
+ && !GC_is_heap_base(buf.AllocationBase)
+ && !is_frame_buffer(p, buf.RegionSize)) {
+# ifdef DEBUG_VIRTUALQUERY
+ GC_dump_meminfo(&buf);
+# endif
if ((char *)p != limit) {
GC_cond_add_roots(base, limit);
base = p;
@@ -981,7 +1077,14 @@ void GC_register_dynamic_libraries()
#ifdef DARWIN
-#include <mach-o/dyld.h>
+/* __private_extern__ hack required for pre-3.4 gcc versions. */
+#ifndef __private_extern__
+# define __private_extern__ extern
+# include <mach-o/dyld.h>
+# undef __private_extern__
+#else
+# include <mach-o/dyld.h>
+#endif
#include <mach-o/getsect.h>
/*#define DARWIN_DEBUG*/