Пример #1
0
void GarbageCollector::collectPartition (int partitionNum)
{
    int i;
    HeapAllocator* heapAllocator;
    vector<AllocatedObject*>* reachableObjects;
    
    /* Get all reachable objects of partition*/
    heapAllocator = ptrVM->getHeapAllocator ();
    reachableObjects = heapAllocator->reachableObjectsForPartition (partitionNum);
    
    /* Insert them one by one in the partition */
    for (i = 0; i < reachableObjects->size (); i++)
    {
        MemoryBlock *memBlock;
        int size;
        AllocatedObject* allocObj;

        size = reachableObjects->at (i)->getClassInfo ()->getSize ();
        memBlock = heapAllocator->allocateInPartition (partitionNum+1, size);

        if (memBlock)
        {
            MemoryBlock *prevMemBlock;
            byte* prevMem;
            byte *mem;
            int j = 0;
            
            allocObj = reachableObjects->at(i);
            prevMemBlock = allocObj->getMemBlock ();
            prevMem = prevMemBlock->getMemory ();
            mem = memBlock->getMemory ();
            ptrVM->updateAddressForAllocatedObject (prevMemBlock->getStartPos (),
                                                    memBlock->getStartPos (),
                                                    allocObj);
            memBlock->setAllocatedVariable (allocObj);
            allocObj->setMemBlock (memBlock);

            /* Copy data from previous block to the new block*/
            for (j = 0; j < memBlock->getSize (); j++)
            {
                mem[j] = prevMem[j];
            }

            heapAllocator->freeAddress (prevMemBlock->getStartPos ());

            /* Update the value of pointer in the reachable objects */
            j = allocObj->totalAddresses () - 1;

            while (j >= 0)
            {
                *allocObj->popAddress () = memBlock->getStartPos ();
                j--;
            }
        }
        else
        {
            break;
        }
    }

    if (i < reachableObjects->size ())
    {
        /* Not all objects have been allocated
         * collect this partition also */
        collectPartition (partitionNum + 1);
        
        /* Insert remaining reachable objects in this partition */
        for (; i < reachableObjects->size (); i++)
        {
            MemoryBlock *memBlock;
            int size;
            AllocatedObject* allocObj;
    
            size = reachableObjects->at (i)->getClassInfo ()->getSize ();
            memBlock = heapAllocator->allocateInPartition (partitionNum+1, size);
    
            if (memBlock)
            {
                MemoryBlock *prevMemBlock;
                int j = 0;
    
                allocObj = reachableObjects->at(i);
                prevMemBlock = allocObj->getMemBlock ();
                ptrVM->updateAddressForAllocatedObject (prevMemBlock->getStartPos (),
                                                        memBlock->getStartPos (),
                                                        allocObj);
                memBlock->setAllocatedVariable (reachableObjects->at (i));
                allocObj->setMemBlock (memBlock);
                
                /* Copy data from previous block to the new block*/
                for (j = 0; j < memBlock->getSize (); j++)
                {
                    memBlock->getMemory ()[i] = prevMemBlock->getMemory ()[i];
                }

                heapAllocator->freeAddress (prevMemBlock->getStartPos ());
    
                /* Update the value of pointer in the reachable objects */
                j = allocObj->totalAddresses () - 1;
                while (j >= 0)
                {
                    *allocObj->popAddress () = memBlock->getStartPos ();
                    j--;
                }
            }
            else
            {
                break;
            }
        }
    }

    delete reachableObjects;
}