/** * Attach a physical arena of the specified size to the receiver. * This reserves the address space within the receiver for the arena, and connects the arena to the list * of those associated to the receiver (in address order). * * @return true if the arena was attached successfully, false otherwise. * @note The memory reseved is not commited. */ bool MM_HeapVirtualMemory::attachArena(MM_EnvironmentBase* env, MM_PhysicalArena* arena, uintptr_t size) { /* Sanity check of the size */ if (getMaximumMemorySize() < size) { return false; } MM_GCExtensionsBase* extensions = env->getExtensions(); MM_MemoryManager* memoryManager = extensions->memoryManager; /* Find the insertion point for the currentArena */ void* candidateBase = memoryManager->getHeapBase(&_vmemHandle); MM_PhysicalArena* insertionHead = NULL; MM_PhysicalArena* insertionTail = _physicalArena; MM_PhysicalArena* currentArena = arena; while (insertionTail) { if ((((uintptr_t)insertionTail->getLowAddress()) - ((uintptr_t)candidateBase)) >= size) { break; } candidateBase = insertionTail->getHighAddress(); insertionHead = insertionTail; insertionTail = insertionTail->getNextArena(); } /* If we have reached the end of the currentArena list, check if there is room between the candidateBase * and the end of virtual memory */ if (!insertionTail) { if ((memoryManager->calculateOffsetToHeapTop(&_vmemHandle, candidateBase)) < size) { return false; } } /* Connect the physical currentArena into the list at the appropriate point */ currentArena->setPreviousArena(insertionHead); currentArena->setNextArena(insertionTail); if (insertionTail) { insertionTail->setPreviousArena(currentArena); } if (insertionHead) { insertionHead->setNextArena(currentArena); } else { _physicalArena = currentArena; } currentArena->setLowAddress(candidateBase); currentArena->setHighAddress((void*)(((uint8_t*)candidateBase) + size)); /* Set the arena state to being attached */ arena->setAttached(true); return true; }