Changeset 101773 in vbox for trunk/src/libs/xpcom18a4/nsprpub
- Timestamp:
- Nov 4, 2023 6:00:28 PM (15 months ago)
- Location:
- trunk/src/libs/xpcom18a4/nsprpub/pr
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/xpcom18a4/nsprpub/pr/include/private/primpl.h
r101772 r101773 1844 1844 extern PRFileDesc *_pr_stderr; 1845 1845 1846 /* Zone allocator */1847 /*1848 ** The zone allocator code has hardcoded pthread types and1849 ** functions, so it can only be used in the pthreads version.1850 ** This can be fixed by replacing the hardcoded pthread types1851 ** and functions with macros that expand to the native thread1852 ** types and functions on each platform.1853 */1854 #if defined(_PR_PTHREADS) && !defined(_PR_DCETHREADS)1855 #define _PR_ZONE_ALLOCATOR1856 #endif1857 1858 #ifdef _PR_ZONE_ALLOCATOR1859 extern void _PR_InitZones(void);1860 extern void _PR_DestroyZones(void);1861 #endif1862 1863 1846 1864 1847 /************************************************************************* -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/malloc/prmem.c
r101772 r101773 44 44 # include <iprt/mem.h> 45 45 #endif 46 47 #ifdef _PR_ZONE_ALLOCATOR48 49 #ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP50 #define PR_FPrintZoneStats VBoxNsprPR_FPrintZoneStats51 #endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */52 53 /*54 ** The zone allocator code must use native mutexes and cannot55 ** use PRLocks because PR_NewLock calls PR_Calloc, resulting56 ** in cyclic dependency of initialization.57 */58 59 #include <string.h>60 61 union memBlkHdrUn;62 63 typedef struct MemoryZoneStr {64 union memBlkHdrUn *head; /* free list */65 pthread_mutex_t lock;66 size_t blockSize; /* size of blocks on this free list */67 PRUint32 locked; /* current state of lock */68 PRUint32 contention; /* counter: had to wait for lock */69 PRUint32 hits; /* allocated from free list */70 PRUint32 misses; /* had to call malloc */71 PRUint32 elements; /* on free list */72 } MemoryZone;73 74 typedef union memBlkHdrUn {75 unsigned char filler[48]; /* fix the size of this beast */76 struct memBlkHdrStr {77 union memBlkHdrUn *next;78 MemoryZone *zone;79 size_t blockSize;80 size_t requestedSize;81 PRUint32 magic;82 } s;83 } MemBlockHdr;84 85 #define MEM_ZONES 786 #define THREAD_POOLS 11 /* prime number for modulus */87 #define ZONE_MAGIC 0x0BADC0DE88 89 static MemoryZone zones[MEM_ZONES][THREAD_POOLS];90 91 static PRBool use_zone_allocator = PR_FALSE;92 93 static void pr_ZoneFree(void *ptr);94 95 void96 _PR_DestroyZones(void)97 {98 int i, j;99 100 if (!use_zone_allocator)101 return;102 103 for (j = 0; j < THREAD_POOLS; j++) {104 for (i = 0; i < MEM_ZONES; i++) {105 MemoryZone *mz = &zones[i][j];106 pthread_mutex_destroy(&mz->lock);107 while (mz->head) {108 MemBlockHdr *hdr = mz->head;109 mz->head = hdr->s.next; /* unlink it */110 #ifdef VBOX_USE_IPRT_IN_NSPR111 RTMemFree(hdr);112 #else113 free(hdr);114 #endif115 mz->elements--;116 }117 }118 }119 use_zone_allocator = PR_FALSE;120 }121 122 /*123 ** pr_FindSymbolInProg124 **125 ** Find the specified data symbol in the program and return126 ** its address.127 */128 129 #ifdef USE_DLFCN130 131 #include <dlfcn.h>132 133 static void *134 pr_FindSymbolInProg(const char *name)135 {136 void *h;137 void *sym;138 139 h = dlopen(0, RTLD_LAZY);140 if (h == NULL)141 return NULL;142 sym = dlsym(h, name);143 (void)dlclose(h);144 return sym;145 }146 147 #elif defined(USE_HPSHL)148 149 #include <dl.h>150 151 static void *152 pr_FindSymbolInProg(const char *name)153 {154 shl_t h = NULL;155 void *sym;156 157 if (shl_findsym(&h, name, TYPE_DATA, &sym) == -1)158 return NULL;159 return sym;160 }161 162 #elif defined(USE_MACH_DYLD)163 164 static void *165 pr_FindSymbolInProg(const char *name)166 {167 /* FIXME: not implemented */168 return NULL;169 }170 171 #else172 173 #error "The zone allocator is not supported on this platform"174 175 #endif176 177 void178 _PR_InitZones(void)179 {180 int i, j;181 char *envp;182 PRBool *sym;183 184 if ((sym = (PRBool *)pr_FindSymbolInProg("nspr_use_zone_allocator")) != NULL) {185 use_zone_allocator = *sym;186 } else if ((envp = getenv("NSPR_USE_ZONE_ALLOCATOR")) != NULL) {187 use_zone_allocator = (atoi(envp) == 1);188 }189 190 if (!use_zone_allocator)191 return;192 193 for (j = 0; j < THREAD_POOLS; j++) {194 for (i = 0; i < MEM_ZONES; i++) {195 MemoryZone *mz = &zones[i][j];196 int rv = pthread_mutex_init(&mz->lock, NULL);197 PR_ASSERT(0 == rv);198 if (rv != 0) {199 goto loser;200 }201 mz->blockSize = 16 << ( 2 * i);202 }203 }204 return;205 206 loser:207 _PR_DestroyZones();208 return;209 }210 211 PR_IMPLEMENT(void)212 PR_FPrintZoneStats(PRFileDesc *debug_out)213 {214 int i, j;215 216 for (j = 0; j < THREAD_POOLS; j++) {217 for (i = 0; i < MEM_ZONES; i++) {218 MemoryZone *mz = &zones[i][j];219 MemoryZone zone = *mz;220 if (zone.elements || zone.misses || zone.hits) {221 PR_fprintf(debug_out,222 "pool: %d, zone: %d, size: %d, free: %d, hit: %d, miss: %d, contend: %d\n",223 j, i, zone.blockSize, zone.elements,224 zone.hits, zone.misses, zone.contention);225 }226 }227 }228 }229 230 static void *231 pr_ZoneMalloc(PRUint32 size)232 {233 void *rv;234 unsigned int zone;235 size_t blockSize;236 MemBlockHdr *mb, *mt;237 MemoryZone *mz;238 239 /* Always allocate a non-zero amount of bytes */240 if (size < 1) {241 size = 1;242 }243 for (zone = 0, blockSize = 16; zone < MEM_ZONES; ++zone, blockSize <<= 2) {244 if (size <= blockSize) {245 break;246 }247 }248 if (zone < MEM_ZONES) {249 pthread_t me = pthread_self();250 unsigned int pool = (PRUptrdiff)me % THREAD_POOLS;251 PRUint32 wasLocked;252 mz = &zones[zone][pool];253 wasLocked = mz->locked;254 pthread_mutex_lock(&mz->lock);255 mz->locked = 1;256 if (wasLocked)257 mz->contention++;258 if (mz->head) {259 mb = mz->head;260 PR_ASSERT(mb->s.magic == ZONE_MAGIC);261 PR_ASSERT(mb->s.zone == mz);262 PR_ASSERT(mb->s.blockSize == blockSize);263 PR_ASSERT(mz->blockSize == blockSize);264 265 mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);266 PR_ASSERT(mt->s.magic == ZONE_MAGIC);267 PR_ASSERT(mt->s.zone == mz);268 PR_ASSERT(mt->s.blockSize == blockSize);269 270 mz->hits++;271 mz->elements--;272 mz->head = mb->s.next; /* take off free list */273 mz->locked = 0;274 pthread_mutex_unlock(&mz->lock);275 276 mt->s.next = mb->s.next = NULL;277 mt->s.requestedSize = mb->s.requestedSize = size;278 279 rv = (void *)(mb + 1);280 return rv;281 }282 283 mz->misses++;284 mz->locked = 0;285 pthread_mutex_unlock(&mz->lock);286 287 #ifdef VBOX_USE_IPRT_IN_NSPR288 mb = (MemBlockHdr *)RTMemAlloc(blockSize + 2 * (sizeof *mb));289 #else290 mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));291 #endif292 if (!mb) {293 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);294 return NULL;295 }296 mb->s.next = NULL;297 mb->s.zone = mz;298 mb->s.magic = ZONE_MAGIC;299 mb->s.blockSize = blockSize;300 mb->s.requestedSize = size;301 302 mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);303 memcpy(mt, mb, sizeof *mb);304 305 rv = (void *)(mb + 1);306 return rv;307 }308 309 /* size was too big. Create a block with no zone */310 blockSize = (size & 15) ? size + 16 - (size & 15) : size;311 #ifdef VBOX_USE_IPRT_IN_NSPR312 mb = (MemBlockHdr *)RTMemAlloc(blockSize + 2 * (sizeof *mb));313 #else314 mb = (MemBlockHdr *)malloc(blockSize + 2 * (sizeof *mb));315 #endif316 if (!mb) {317 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);318 return NULL;319 }320 mb->s.next = NULL;321 mb->s.zone = NULL;322 mb->s.magic = ZONE_MAGIC;323 mb->s.blockSize = blockSize;324 mb->s.requestedSize = size;325 326 mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);327 memcpy(mt, mb, sizeof *mb);328 329 rv = (void *)(mb + 1);330 return rv;331 }332 333 334 static void *335 pr_ZoneCalloc(PRUint32 nelem, PRUint32 elsize)336 {337 PRUint32 size = nelem * elsize;338 void *p = pr_ZoneMalloc(size);339 if (p) {340 memset(p, 0, size);341 }342 return p;343 }344 345 static void *346 pr_ZoneRealloc(void *oldptr, PRUint32 bytes)347 {348 void *rv;349 MemBlockHdr *mb;350 int ours;351 MemBlockHdr phony;352 353 if (!oldptr)354 return pr_ZoneMalloc(bytes);355 mb = (MemBlockHdr *)((char *)oldptr - (sizeof *mb));356 PR_ASSERT(mb->s.magic == ZONE_MAGIC);357 if (mb->s.magic != ZONE_MAGIC) {358 /* Maybe this just came from ordinary malloc */359 #ifdef DEBUG360 fprintf(stderr,361 "Warning: reallocing memory block %p from ordinary malloc\n",362 oldptr);363 #endif364 /* We don't know how big it is. But we can fix that. */365 #ifdef VBOX_USE_IPRT_IN_NSPR366 oldptr = RTMemRealloc(oldptr, bytes);367 #else368 oldptr = realloc(oldptr, bytes);369 #endif370 if (!oldptr) {371 if (bytes) {372 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);373 return oldptr;374 }375 }376 phony.s.requestedSize = bytes;377 mb = &phony;378 ours = 0;379 } else {380 size_t blockSize = mb->s.blockSize;381 MemBlockHdr *mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);382 383 PR_ASSERT(mt->s.magic == ZONE_MAGIC);384 PR_ASSERT(mt->s.zone == mb->s.zone);385 PR_ASSERT(mt->s.blockSize == blockSize);386 387 if (bytes <= blockSize) {388 /* The block is already big enough. */389 mt->s.requestedSize = mb->s.requestedSize = bytes;390 return oldptr;391 }392 ours = 1;393 }394 395 rv = pr_ZoneMalloc(bytes);396 if (rv) {397 if (oldptr && mb->s.requestedSize)398 memcpy(rv, oldptr, mb->s.requestedSize);399 if (ours)400 pr_ZoneFree(oldptr);401 else if (oldptr)402 #ifdef VBOX_USE_IPRT_IN_NSPR403 RTMemFree(oldptr);404 #else405 free(oldptr);406 #endif407 }408 return rv;409 }410 411 static void412 pr_ZoneFree(void *ptr)413 {414 MemBlockHdr *mb, *mt;415 MemoryZone *mz;416 size_t blockSize;417 PRUint32 wasLocked;418 419 if (!ptr)420 return;421 422 mb = (MemBlockHdr *)((char *)ptr - (sizeof *mb));423 424 if (mb->s.magic != ZONE_MAGIC) {425 /* maybe this came from ordinary malloc */426 #ifdef DEBUG427 fprintf(stderr,428 "Warning: freeing memory block %p from ordinary malloc\n", ptr);429 #endif430 #ifdef VBOX_USE_IPRT_IN_NSPR431 RTMemFree(ptr);432 #else433 free(ptr);434 #endif435 return;436 }437 438 blockSize = mb->s.blockSize;439 mz = mb->s.zone;440 mt = (MemBlockHdr *)(((char *)(mb + 1)) + blockSize);441 PR_ASSERT(mt->s.magic == ZONE_MAGIC);442 PR_ASSERT(mt->s.zone == mz);443 PR_ASSERT(mt->s.blockSize == blockSize);444 if (!mz) {445 PR_ASSERT(blockSize > 65536);446 /* This block was not in any zone. Just free it. */447 #ifdef VBOX_USE_IPRT_IN_NSPR448 RTMemFree(mb);449 #else450 free(mb);451 #endif452 return;453 }454 PR_ASSERT(mz->blockSize == blockSize);455 wasLocked = mz->locked;456 pthread_mutex_lock(&mz->lock);457 mz->locked = 1;458 if (wasLocked)459 mz->contention++;460 mt->s.next = mb->s.next = mz->head; /* put on head of list */461 mz->head = mb;462 mz->elements++;463 mz->locked = 0;464 pthread_mutex_unlock(&mz->lock);465 }466 467 PR_IMPLEMENT(void *) PR_Malloc(PRUint32 size)468 {469 if (!_pr_initialized) _PR_ImplicitInitialization();470 471 #ifdef VBOX_USE_IPRT_IN_NSPR472 return use_zone_allocator ? pr_ZoneMalloc(size) : RTMemAlloc(RT_MAX(size, 1));473 #else474 return use_zone_allocator ? pr_ZoneMalloc(size) : malloc(size);475 #endif476 }477 478 PR_IMPLEMENT(void *) PR_Calloc(PRUint32 nelem, PRUint32 elsize)479 {480 if (!_pr_initialized) _PR_ImplicitInitialization();481 482 return use_zone_allocator ?483 #ifdef VBOX_USE_IPRT_IN_NSPR484 pr_ZoneCalloc(nelem, elsize) : RTMemAllocZ(RT_MAX(nelem * (size_t)elsize, 1));485 #else486 pr_ZoneCalloc(nelem, elsize) : calloc(nelem, elsize);487 #endif488 }489 490 PR_IMPLEMENT(void *) PR_Realloc(void *ptr, PRUint32 size)491 {492 if (!_pr_initialized) _PR_ImplicitInitialization();493 494 #ifdef VBOX_USE_IPRT_IN_NSPR495 return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : RTMemRealloc(ptr, size);496 #else497 return use_zone_allocator ? pr_ZoneRealloc(ptr, size) : realloc(ptr, size);498 #endif499 }500 501 PR_IMPLEMENT(void) PR_Free(void *ptr)502 {503 if (use_zone_allocator)504 pr_ZoneFree(ptr);505 else506 #ifdef VBOX_USE_IPRT_IN_NSPR507 RTMemFree(ptr);508 #else509 free(ptr);510 #endif511 }512 513 #else /* !defined(_PR_ZONE_ALLOCATOR) */514 46 515 47 /* … … 574 106 } 575 107 576 #endif /* _PR_ZONE_ALLOCATOR */577 -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/misc/prinit.c
r101772 r101773 178 178 #ifdef VBOX_USE_IPRT_IN_NSPR 179 179 RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE); 180 #endif181 #ifdef _PR_ZONE_ALLOCATOR182 _PR_InitZones();183 180 #endif 184 181 #ifdef WINNT -
trunk/src/libs/xpcom18a4/nsprpub/pr/src/pthreads/ptthread.c
r101770 r101773 1027 1027 _PR_CleanupLayerCache(); 1028 1028 _PR_CleanupEnv(); 1029 #ifdef _PR_ZONE_ALLOCATOR1030 _PR_DestroyZones();1031 #endif1032 1029 _pr_initialized = PR_FALSE; 1033 1030 return PR_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.