diff options
author | Bryce McKinlay <bryce@gcc.gnu.org> | 2004-08-12 21:14:30 +0000 |
---|---|---|
committer | Bryce McKinlay <bryce@gcc.gnu.org> | 2004-08-12 21:14:30 +0000 |
commit | 4e638f718c43d7525f7d833b52e9702e5b6dc0ed (patch) | |
tree | c6eada4017a3d213b1edf5cb23b7883ac3035290 /boehm-gc/dyn_load.c | |
parent | b59596cbb42f36d72f2b91755464eac6826e0b43 (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.c | 113 |
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*/ |