summaryrefslogtreecommitdiff
path: root/pr/src/malloc/prmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/malloc/prmem.c')
-rw-r--r--pr/src/malloc/prmem.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/pr/src/malloc/prmem.c b/pr/src/malloc/prmem.c
index 0a70b439..ef8fdc74 100644
--- a/pr/src/malloc/prmem.c
+++ b/pr/src/malloc/prmem.c
@@ -97,20 +97,79 @@ _PR_DestroyZones(void)
while (mz->head) {
MemBlockHdr *hdr = mz->head;
mz->head = hdr->s.next; /* unlink it */
- pr_ZoneFree(hdr);
+ free(hdr);
mz->elements--;
}
}
}
+ use_zone_allocator = PR_FALSE;
}
+/*
+** pr_FindSymbolInProg
+**
+** Find the specified data symbol in the program and return
+** its address.
+*/
+
+#ifdef USE_DLFCN
+
+#include <dlfcn.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+ void *h;
+ void *sym;
+
+ h = dlopen(0, RTLD_LAZY);
+ if (h == NULL)
+ return NULL;
+ sym = dlsym(h, name);
+ (void)dlclose(h);
+ return sym;
+}
+
+#elif defined(USE_HPSHL)
+
+#include <dl.h>
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+ shl_t h = NULL;
+ void *sym;
+
+ if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1)
+ return NULL;
+ return sym;
+}
+
+#elif defined(USE_MACH_DYLD)
+
+static void *
+pr_FindSymbolInProg(const char *name)
+{
+ /* FIXME: not implemented */
+ return NULL;
+}
+
+#else
+
+#error "The zone allocator is not supported on this platform"
+
+#endif
+
void
_PR_InitZones(void)
{
int i, j;
char *envp;
+ PRBool *sym;
- if (envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) {
+ if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) {
+ use_zone_allocator = *sym;
+ } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) {
use_zone_allocator = (atoi(envp) == 1);
}
@@ -174,7 +233,7 @@ pr_ZoneMalloc(PRUint32 size)
}
if (zone < MEM_ZONES) {
pthread_t me = pthread_self();
- unsigned int pool = (ptrdiff_t)me % THREAD_POOLS;
+ unsigned int pool = (PRUptrdiff)me % THREAD_POOLS;
PRUint32 wasLocked;
mz = &zones[zone][pool];
wasLocked = mz->locked;
@@ -275,6 +334,11 @@ pr_ZoneRealloc(void *oldptr, PRUint32 bytes)
PR_ASSERT(mb->s.magic == ZONE_MAGIC);
if (mb->s.magic != ZONE_MAGIC) {
/* Maybe this just came from ordinary malloc */
+#ifdef DEBUG
+ fprintf(stderr,
+ "Warning: reallocing memory block %p from ordinary malloc\n",
+ oldptr);
+#endif
/* We don't know how big it is. But we can fix that. */
oldptr = realloc(oldptr, bytes);
if (!oldptr) {
@@ -329,6 +393,10 @@ pr_ZoneFree(void *ptr)
if (mb->s.magic != ZONE_MAGIC) {
/* maybe this came from ordinary malloc */
+#ifdef DEBUG
+ fprintf(stderr,
+ "Warning: freeing memory block %p from ordinary malloc\n", ptr);
+#endif
free(ptr);
return;
}
@@ -342,7 +410,7 @@ pr_ZoneFree(void *ptr)
if (!mz) {
PR_ASSERT(blockSize > 65536);
/* This block was not in any zone. Just free it. */
- free(ptr);
+ free(mb);
return;
}
PR_ASSERT(mz->blockSize == blockSize);