Ejemplo n.º 1
0
bool MemMgr::GrowOrShrinkStack(StackSpace *space, POLYUNSIGNED newSize)
{
    size_t iSpace = newSize*sizeof(PolyWord);
    PolyWord *newSpace = (PolyWord*)osMemoryManager->Allocate(iSpace, PERMISSION_READ|PERMISSION_WRITE);
    if (newSpace == 0)
    {
        if (debugOptions & DEBUG_MEMMGR)
            Log("MMGR: Unable to change size of stack %p from %lu to %lu: insufficient space\n",
                space, space->spaceSize(), newSize);
        return false;
    }
    // The size may have been rounded up to a block boundary.
    newSize = iSpace/sizeof(PolyWord);
    try {
        AddTree(space, newSpace, newSpace+newSize);
    }
    catch (std::bad_alloc a) {
        RemoveTree(space, newSpace, newSpace+newSize);
        delete space;
        return 0;
    }
    CopyStackFrame(space->stack(), space->spaceSize(), (StackObject*)newSpace, newSize);
    if (debugOptions & DEBUG_MEMMGR)
        Log("MMGR: Size of stack %p changed from %lu to %lu at %p\n", space, space->spaceSize(), newSize, newSpace);
    RemoveTree(space); // Remove it BEFORE freeing the space - another thread may allocate it
    osMemoryManager->Free(space->bottom, (char*)space->top - (char*)space->bottom);
    space->bottom = newSpace;
    space->top = newSpace+newSize;
    return true;
}
Ejemplo n.º 2
0
// Delete a local space and remove it from the table.
bool MemMgr::DeleteLocalSpace(LocalMemSpace *sp)
{
    for (unsigned i = 0; i < nlSpaces; i++)
    {
        if (lSpaces[i] == sp)
        {
            if (debugOptions & DEBUG_MEMMGR)
                Log("MMGR: Deleted local %s space %p\n", sp->spaceTypeString(), sp);
            currentHeapSize -= sp->spaceSize();
            globalStats.setSize(PSS_TOTAL_HEAP, currentHeapSize * sizeof(PolyWord));
            if (sp->allocationSpace) currentAllocSpace -= sp->spaceSize();
            RemoveTree(sp);
            delete sp;
            nlSpaces--;
            while (i < nlSpaces)
            {
                lSpaces[i] = lSpaces[i+1];
                i++;
            }
            return true;
        }
    }
    ASSERT(false); // It should always be in the table.
    return false;
}
Ejemplo n.º 3
0
StackSpace *MemMgr::NewStackSpace(POLYUNSIGNED size)
{
    PLocker lock(&stackSpaceLock);

    try {
        StackSpace *space = new StackSpace;
        size_t iSpace = size*sizeof(PolyWord);
        space->bottom =
            (PolyWord*)osMemoryManager->Allocate(iSpace, PERMISSION_READ|PERMISSION_WRITE);
        if (space->bottom == 0)
        {
            if (debugOptions & DEBUG_MEMMGR)
                Log("MMGR: New stack space: insufficient space\n");
            delete space;
            return 0;
        }

        // The size may have been rounded up to a block boundary.
        size = iSpace/sizeof(PolyWord);
        space->top = space->bottom + size;
        space->spaceType = ST_STACK;
        space->isMutable = true;

        // Extend the permanent memory table and add this space to it.
        StackSpace **table =
            (StackSpace **)realloc(sSpaces, (nsSpaces+1) * sizeof(StackSpace *));
        if (table == 0)
        {
            if (debugOptions & DEBUG_MEMMGR)
                Log("MMGR: New stack space: table realloc failed\n");
            delete space;
            return 0;
        }
        sSpaces = table;
        // Add the stack space to the tree.  This ensures that operations such as
        // LocalSpaceForAddress will work for addresses within the stack.  We can
        // get them in the RTS with functions such as quot_rem and exception stack.
        // It's not clear whether they really appear in the GC.
        try {
            AddTree(space);
        }
        catch (std::bad_alloc a) {
            RemoveTree(space);
            delete space;
            return 0;
        }
        sSpaces[nsSpaces++] = space;
        if (debugOptions & DEBUG_MEMMGR)
            Log("MMGR: New stack space %p allocated at %p size %lu\n", space, space->bottom, space->spaceSize());
        return space;
    }
    catch (std::bad_alloc a) {
        if (debugOptions & DEBUG_MEMMGR)
            Log("MMGR: New stack space: \"new\" failed\n");
        return 0;
    }
}
Ejemplo n.º 4
0
void MemMgr::DeleteExportSpaces(void)
{
    while (neSpaces > 0)
    {
        PermanentMemSpace *space = eSpaces[--neSpaces];
        RemoveTree(space);
        delete(space);
    }
}
Ejemplo n.º 5
0
// If we have saved the state rather than exported a function we turn the exported
// spaces into permanent ones, removing existing permanent spaces at the same or
// lower level.
bool MemMgr::PromoteExportSpaces(unsigned hierarchy)
{
    // Create a new table big enough to hold all the permanent and export spaces
    PermanentMemSpace **pTable =
        (PermanentMemSpace **)calloc(npSpaces+neSpaces, sizeof(PermanentMemSpace *));
    if (pTable == 0) return false;
    unsigned newSpaces = 0;
    // Save permanent spaces at a lower hierarchy.  Others are converted into
    // local spaces.  Most or all items will have been copied from these spaces
    // into an export space but there could be items reachable only from the stack.
    for (unsigned i = 0; i < npSpaces; i++)
    {
        PermanentMemSpace *pSpace = pSpaces[i];
        if (pSpace->hierarchy < hierarchy)
            pTable[newSpaces++] = pSpace;
        else
        {
            try {
                // Turn this into a local space.
                // Remove this from the tree - AddLocalSpace will make an entry for the local version.
                RemoveTree(pSpace);
                LocalMemSpace *space = new LocalMemSpace;
                space->top = space->fullGCLowerLimit = pSpace->top;
                space->bottom = space->upperAllocPtr = space->lowerAllocPtr = pSpace->bottom;
                space->isMutable = pSpace->isMutable;
                space->isOwnSpace = true;
                if (! space->bitmap.Create(space->top-space->bottom) || ! AddLocalSpace(space))
                    return false;
                currentHeapSize += space->spaceSize();
                globalStats.setSize(PSS_TOTAL_HEAP, currentHeapSize * sizeof(PolyWord));
            }
            catch (std::bad_alloc a) {
                return false;
            }
        }
    }
    // Save newly exported spaces.
    for (unsigned j = 0; j < neSpaces; j++)
    {
        PermanentMemSpace *space = eSpaces[j];
        space->hierarchy = hierarchy; // Set the hierarchy of the new spaces.
        space->spaceType = ST_PERMANENT;
        // Put a dummy object to fill up the unused space.
        if (space->topPointer != space->top)
            FillUnusedSpace(space->topPointer, space->top - space->topPointer);
        // Put in a dummy object to fill the rest of the space.
        pTable[newSpaces++] = space;
    }
    neSpaces = 0;
    npSpaces = newSpaces;
    free(pSpaces);
    pSpaces = pTable;

    return true;
}
Ejemplo n.º 6
0
// Before we import a hierarchical saved state we need to turn any previously imported
// spaces into local spaces.
bool MemMgr::DemoteImportSpaces()
{
    // Create a new permanent space table.
    PermanentMemSpace **table =
        (PermanentMemSpace **)calloc(npSpaces, sizeof(PermanentMemSpace *));
    if (table == NULL) return false;
    unsigned newSpaces = 0;
    for (unsigned i = 0; i < npSpaces; i++)
    {
        PermanentMemSpace *pSpace = pSpaces[i];
        if (pSpace->hierarchy == 0) // Leave truly permanent spaces
            table[newSpaces++] = pSpace;
        else
        {
            try {
                // Turn this into a local space.
                // Remove this from the tree - AddLocalSpace will make an entry for the local version.
                RemoveTree(pSpace);
                LocalMemSpace *space = new LocalMemSpace;
                space->top = pSpace->top;
                // Space is allocated in local areas from the top down.  This area is full and
                // all data is in the old generation.  The area can be recovered by a full GC.
                space->bottom = space->upperAllocPtr = space->lowerAllocPtr =
                    space->fullGCLowerLimit = pSpace->bottom;
                space->isMutable = pSpace->isMutable;
                space->isOwnSpace = true;
                if (! space->bitmap.Create(space->top-space->bottom) || ! AddLocalSpace(space))
                {
                    if (debugOptions & DEBUG_MEMMGR)
                        Log("MMGR: Unable to convert saved state space %p into local space\n", pSpace);
                    return false;
                }
                if (debugOptions & DEBUG_MEMMGR)
                    Log("MMGR: Converted saved state space %p into local %smutable space %p\n",
                            pSpace, pSpace->isMutable ? "im": "", space);
                currentHeapSize += space->spaceSize();
                globalStats.setSize(PSS_TOTAL_HEAP, currentHeapSize * sizeof(PolyWord));
            }
            catch (std::bad_alloc a) {
                if (debugOptions & DEBUG_MEMMGR)
                    Log("MMGR: Unable to convert saved state space %p into local space (\"new\" failed)\n", pSpace);
                return false;
            }
        }
    }
    npSpaces = newSpaces;
    free(pSpaces);
    pSpaces = table;

    return true;
}
Ejemplo n.º 7
0
// Create and initialise a new export space and add it to the table.
PermanentMemSpace* MemMgr::NewExportSpace(POLYUNSIGNED size, bool mut, bool noOv)
{
    try {
        PermanentMemSpace *space = new PermanentMemSpace;
        space->spaceType = ST_EXPORT;
        space->isMutable = mut;
        space->noOverwrite = noOv;
        space->index = nextIndex++;
        // Allocate the memory itself.
        size_t iSpace = size*sizeof(PolyWord);
        space->bottom  =
            (PolyWord*)osMemoryManager->Allocate(iSpace, PERMISSION_READ|PERMISSION_WRITE|PERMISSION_EXEC);

        if (space->bottom == 0)
        {
            delete space;
            return 0;
        }
        space->isOwnSpace = true;
 
        // The size may have been rounded up to a block boundary.
        size = iSpace/sizeof(PolyWord);
        space->top = space->bottom + size;
        space->topPointer = space->bottom;

        // Add to the table.
        PermanentMemSpace **table = (PermanentMemSpace **)realloc(eSpaces, (neSpaces+1) * sizeof(PermanentMemSpace *));
        if (table == 0)
        {
            delete space;
            return 0;
        }
        eSpaces = table;
        try {
            AddTree(space);
        }
        catch (std::bad_alloc a) {
            RemoveTree(space);
            delete space;
            return 0;
        }
        eSpaces[neSpaces++] = space;
        return space;
    }
    catch (std::bad_alloc a) {
        return 0;
    }
}
Ejemplo n.º 8
0
// Create an entry for a permanent space.
PermanentMemSpace* MemMgr::NewPermanentSpace(PolyWord *base, POLYUNSIGNED words,
                                             unsigned flags, unsigned index, unsigned hierarchy /*= 0*/)
{
    try {
        PermanentMemSpace *space = new PermanentMemSpace;
        space->bottom = base;
        space->topPointer = space->top = space->bottom + words;
        space->spaceType = ST_PERMANENT;
        space->isMutable = flags & MTF_WRITEABLE ? true : false;
        space->noOverwrite = flags & MTF_NO_OVERWRITE ? true : false;
        space->byteOnly = flags & MTF_BYTES ? true : false;
        space->index = index;
        space->hierarchy = hierarchy;
        if (index >= nextIndex) nextIndex = index+1;

        // Extend the permanent memory table and add this space to it.
        PermanentMemSpace **table =
            (PermanentMemSpace **)realloc(pSpaces, (npSpaces+1) * sizeof(PermanentMemSpace *));
        if (table == 0)
        {
            delete space;
            return 0;
        }
        pSpaces = table;
        try {
            AddTree(space);
        }
        catch (std::bad_alloc a) {
            RemoveTree(space);
            delete space;
            return 0;
        }
        pSpaces[npSpaces++] = space;
        return space;
    }
    catch (std::bad_alloc a) {
        return 0;
    }
}
Ejemplo n.º 9
0
// Add a local memory space to the table.
bool MemMgr::AddLocalSpace(LocalMemSpace *space)
{
    // Add to the table.
    LocalMemSpace **table = (LocalMemSpace **)realloc(lSpaces, (nlSpaces+1) * sizeof(LocalMemSpace *));
    if (table == 0) return false;
    lSpaces = table;
    // Update the B-tree.
    try {
        AddTree(space);
    }
    catch (std::bad_alloc a) {
        RemoveTree(space);
        return false;
    }
    // The entries in the local table are ordered so that the copy phase of the full
    // GC simply has to copy to an entry earlier in the table.  Immutable spaces come
    // first, followed by mutable spaces and finally allocation spaces.
    if (space->allocationSpace)
        lSpaces[nlSpaces++] = space; // Just add at the end
    else if (space->isMutable)
    {
        // Add before the allocation spaces
        unsigned s;
        for (s = nlSpaces; s > 0 && lSpaces[s-1]->allocationSpace; s--)
            lSpaces[s] = lSpaces[s-1];
        lSpaces[s] = space;
        nlSpaces++;
    }
    else
    {
        // Immutable space: Add before the mutable spaces
        unsigned s;
        for (s = nlSpaces; s > 0 && lSpaces[s-1]->isMutable; s--)
            lSpaces[s] = lSpaces[s-1];
        lSpaces[s] = space;
        nlSpaces++;
    }
    return true;
}
Ejemplo n.º 10
0
//
//   This file contains the C++ code from Program 11.20 of
//   "Data Structures and Algorithms
//    with Object-Oriented Design Patterns in C++"
//   by Bruno R. Preiss.
//
//   Copyright (c) 1998 by Bruno R. Preiss, P.Eng.  All rights reserved.
//
//   http://www.pads.uwaterloo.ca/Bruno.Preiss/books/opus4/programs/pgm11_20.cpp
//
Object& BinomialQueue::DequeueMin ()
{
    if (count == 0)
	throw domain_error ("priority queue is empty");

    BinomialTree& minTree = FindMinTree ();
    RemoveTree (minTree);

    BinomialQueue queue;
    while (minTree.Degree () > 0)
    {
	BinomialTree& child = minTree.Subtree (0);

	minTree.DetachSubtree (child);
	queue.AddTree (child);
    }
    Merge (queue);

    Object& result = minTree.Key ();
    minTree.RescindOwnership ();
    delete &minTree;

    return result;
}
Ejemplo n.º 11
0
// Delete a stack when a thread has finished.
// This can be called by an ML thread so needs an interlock.
bool MemMgr::DeleteStackSpace(StackSpace *space)
{
    PLocker lock(&stackSpaceLock);

    for (unsigned i = 0; i < nsSpaces; i++)
    {
        if (sSpaces[i] == space)
        {
            RemoveTree(space);
            delete space;
            nsSpaces--;
            while (i < nsSpaces)
            {
                sSpaces[i] = sSpaces[i+1];
                i++;
            }
            if (debugOptions & DEBUG_MEMMGR)
                Log("MMGR: Deleted stack space %p\n", space);
            return true;
        }
    }
    ASSERT(false); // It should always be in the table.
    return false;
}
Ejemplo n.º 12
0
void TreeViewWidget::keyPressEvent(QKeyEvent *e)
{
	ActionNode x;
	switch (e->key())
	{
	case Qt::Key_Left:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		if (mode == Mode::MOVE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Translate(QVector3D(-0.5, 0.0, 0.0));
		}
		else if (mode == Mode::ROTATE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Rotate(-15, QVector3D(0.0, 1.0, 0.0));
		}
		else if (mode == Mode::ZOOM)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Scale(QVector2D(0.9, 1.0));
		}
		break;
	case Qt::Key_Right:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		if (mode == Mode::MOVE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Translate(QVector3D(0.5, 0.0, 0.0));
		}
		else if (mode == Mode::ROTATE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Rotate(15, QVector3D(0.0, 1.0, 0.0));
		}
		else if (mode == Mode::ZOOM)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Scale(QVector2D(1.1, 1.0));
		}
		break;
	case Qt::Key_Up:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		if (mode == Mode::MOVE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Translate(QVector3D(0.0, 0.5, 0.0));
		}
		else if (mode == Mode::ROTATE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Rotate(-15, QVector3D(1.0, 0.0, 0.0));
		}
		else if (mode == Mode::ZOOM)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Scale(QVector2D(1.0, 0.9));
		}
		break;
	case Qt::Key_Down:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		if (mode == Mode::MOVE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Translate(QVector3D(0.0, -0.5, 0.0));
		}
		else if (mode == Mode::ROTATE)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Rotate(15, QVector3D(1.0, 0.0, 0.0));
		}
		else if (mode == Mode::ZOOM)
		{
			for (int i = 0; i < selectedList.size(); i++)
				selectedList[i]->Scale(QVector2D(1.0, 1.1));
		}
		break;
	case Qt::Key_Comma:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		for (int i = 0; i < selectedList.size(); i++)
			selectedList[i]->Translate(QVector3D(0.0, 0.0, -0.5));
        break;
	case Qt::Key_Period:
		if (!onmove && (mode == Mode::MOVE || mode == Mode::ROTATE || mode == Mode::ZOOM))
		{
			x.operation = ActionNode::ALTER;
			for (int i = 0; i < selectedList.size(); i++)
			{
				QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
				TreeInfo info(selectedList[i]->GetModelName(), path);
				x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
			}
			thestack.PushToUndo(x);
			emit Pushed();
			onmove = true;
		}
		for (int i = 0; i < selectedList.size(); i++)
			selectedList[i]->Translate(QVector3D(0.0, 0.0, 0.5));
		break;
	case Qt::Key_G:
		LoadBGImage("bg2.jpg");
        break;

    case Qt::Key_Control:
        groupSelecting = true; break;
    case Qt::Key_Shift:
        shiftdown = true; break;
    case Qt::Key_Delete:
		x.operation = ActionNode::REMOVE;
        for(int i=0;i<selectedList.size();i++)
        {
			QString path = DBManager::Instance()->FindPathByTreeName(selectedList[i]->GetModelName());
			TreeInfo info(selectedList[i]->GetModelName(), path);
			x.changedTrees.push_back(TreeNode(selectedList[i]->GetName(), info, selectedList[i]->GetPosition(), selectedList[i]->GetEulerAngles(), selectedList[i]->GetScale()));
            RemoveTree(selectedList[i]->Name());
        }
		thestack.PushToUndo(x);
		emit Pushed();
        selectedList.clear();
        break;

    case Qt::Key_X:
        /*debug*/
        ClearAllTrees();
        /*debug*/
        break;
    }
	
    update();
}