void *algmalloc(size_t size) { void *ptr = NULL; struct blockHeader *node; // Round size to next multiple of 4 size += 3; size &=~3; // If there is no freeList, call sbrk and initialize one if (freeList == NULL) { ptr = allocateNewBlock(size); } else { // Search the free list for a big enough block to use node = searchFreeList(size); if (node != NULL) { if (node->size == size) { ptr = (char*)node + headerSize; removeNodeFromFreeList(node); // Make sure node has enough space to be resized and make room for new block header } else if (node->size >= (size + headerSize)) { node = shrinkBlock(node, size); ptr = (char*)node + headerSize; } else { ptr = allocateNewBlock(size); } } else { // Suitable block wasn't found, allocate a new one ptr = allocateNewBlock(size); } } return ptr; }
CheckedBoolean CopiedSpace::getFreshBlock(AllocationEffort allocationEffort, CopiedBlock** outBlock) { CopiedBlock* block = 0; if (allocationEffort == AllocationMustSucceed) { if (HeapBlock* heapBlock = m_heap->blockAllocator().allocate()) block = new (NotNull, heapBlock) CopiedBlock(heapBlock->m_allocation); else if (!allocateNewBlock(&block)) { *outBlock = 0; ASSERT_NOT_REACHED(); return false; } } else { ASSERT(allocationEffort == AllocationCanFail); if (m_heap->shouldCollect()) m_heap->collect(Heap::DoNotSweep); if (!getFreshBlock(AllocationMustSucceed, &block)) { *outBlock = 0; ASSERT_NOT_REACHED(); return false; } } ASSERT(block); ASSERT(is8ByteAligned(block->m_offset)); *outBlock = block; return true; }