MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / claim_more_memory

Function claim_more_memory

system/lib/emmalloc.c:457–544  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

455}
456
457static bool claim_more_memory(size_t numBytes) {
458#ifdef EMMALLOC_VERBOSE
459 MAIN_THREAD_ASYNC_EM_ASM(out('claim_more_memory(numBytes='+Number($0)+ ')'), numBytes);
460#endif
461
462#ifdef EMMALLOC_MEMVALIDATE
463 validate_memory_regions();
464#endif
465
466 // Make sure we always send sbrk requests with the same alignment that sbrk()
467 // allocates memory at. Otherwise we will not properly interpret returned memory
468 // to form a seamlessly contiguous region with earlier root regions, which would
469 // lead to inefficiently treating the sbrk()ed region to be a new disjoint root
470 // region.
471 numBytes = (size_t)ALIGN_UP(numBytes, MALLOC_ALIGNMENT);
472
473 // Claim memory via sbrk
474 assert((int64_t)numBytes >= 0);
475 uint8_t *startPtr = (uint8_t*)_sbrk64((int64_t)numBytes);
476 if ((intptr_t)startPtr == -1) {
477#ifdef EMMALLOC_VERBOSE
478 MAIN_THREAD_ASYNC_EM_ASM(err('claim_more_memory: sbrk failed!'));
479#endif
480 return false;
481 }
482#ifdef EMMALLOC_VERBOSE
483 MAIN_THREAD_ASYNC_EM_ASM(out('claim_more_memory: claimed ' + ptrToString($0) + ' - ' + ptrToString($1) + ' (' + Number($2) + ' bytes) via sbrk()'), startPtr, startPtr + numBytes, numBytes);
484#endif
485 assert(HAS_ALIGNMENT(startPtr, alignof(size_t)));
486 uint8_t *endPtr = startPtr + numBytes;
487
488 // Create a sentinel region at the end of the new heap block
489 Region *endSentinelRegion = (Region*)(endPtr - sizeof(Region));
490 create_used_region(endSentinelRegion, sizeof(Region));
491#ifdef EMMALLOC_VERBOSE
492 MAIN_THREAD_ASYNC_EM_ASM(out('claim_more_memory: created a sentinel memory region at address ' + ptrToString($0)), endSentinelRegion);
493#endif
494
495 // If we are the sole user of sbrk(), it will feed us continuous/consecutive memory addresses - take advantage
496 // of that if so: instead of creating two disjoint memory regions blocks, expand the previous one to a larger size.
497 uint8_t *previousSbrkEndAddress = listOfAllRegions ? listOfAllRegions->endPtr : 0;
498 if (startPtr == previousSbrkEndAddress) {
499#ifdef EMMALLOC_VERBOSE
500 MAIN_THREAD_ASYNC_EM_ASM(err('claim_more_memory: sbrk() returned a region contiguous to last root region, expanding the existing root region'));
501#endif
502 Region *prevEndSentinel = prev_region((Region*)startPtr);
503 assert(debug_region_is_consistent(prevEndSentinel));
504 assert(region_is_in_use(prevEndSentinel));
505 Region *prevRegion = prev_region(prevEndSentinel);
506 assert(debug_region_is_consistent(prevRegion));
507
508 listOfAllRegions->endPtr = endPtr;
509
510 // Two scenarios, either the last region of the previous block was in use, in which case we need to create
511 // a new free region in the newly allocated space; or it was free, in which case we can extend that region
512 // to cover a larger size.
513 if (region_is_free(prevRegion)) {
514 size_t newFreeRegionSize = (uint8_t*)endSentinelRegion - (uint8_t*)prevRegion;

Callers 2

initialize_emmalloc_heapFunction · 0.85
allocate_memoryFunction · 0.85

Calls 14

validate_memory_regionsFunction · 0.85
_sbrk64Function · 0.85
ptrToStringFunction · 0.85
create_used_regionFunction · 0.85
prev_regionFunction · 0.85
region_is_in_useFunction · 0.85
region_is_freeFunction · 0.85
unlink_from_free_listFunction · 0.85
create_free_regionFunction · 0.85
link_to_free_listFunction · 0.85
outFunction · 0.50

Tested by

no test coverage detected