Exemple #1
0
void ScanAddress::ScanAddressesInRegion(PolyWord *region, PolyWord *end)
{
    PolyWord *pt = region;
    while (pt < end)
    {
        pt++; // Skip length word.
        // pt actually points AT the object here.
        PolyObject *obj = (PolyObject*)pt;
        if (obj->ContainsForwardingPtr())    /* skip over moved object */
        {
            // We can now get multiple forwarding pointers as a result
            // of applying ShareData repeatedly.  Perhaps we should
            // turn the forwarding pointers back into normal words in
            // an extra pass.
            while (obj->ContainsForwardingPtr())
                obj = obj->GetForwardingPtr();
            ASSERT(obj->ContainsNormalLengthWord());
            CheckObject(obj);
            pt += obj->Length();
        }
        else
        {
            ASSERT(obj->ContainsNormalLengthWord());
            POLYUNSIGNED length = obj->Length();
            if (pt+length > end)
                Crash("Malformed object at %p - length %lu\n", pt, length);
            if (length != 0)
                ScanAddressesInObject(obj);
            pt += length;
        }
    }
}
Exemple #2
0
void ProcessFixupAddress::FixupItems (DepthVector *v)
{
    POLYUNSIGNED  N = v->nitems;
    Item *V = v->vector;
    for (POLYUNSIGNED i = 0; i < N; i++)
    {
        ScanAddressesInObject(V[i].pt, V[i].L);
    }
}
Exemple #3
0
// General purpose object processor,  Processes all the addresses in an object.
// Handles the various kinds of object that may contain addresses.
void ScanAddress::ScanAddressesInObject(PolyObject *obj, POLYUNSIGNED lengthWord)
{
    do
    {
        ASSERT (OBJ_IS_LENGTH(lengthWord));
    
        if (OBJ_IS_BYTE_OBJECT(lengthWord))
            return; /* Nothing more to do */
    
        POLYUNSIGNED length = OBJ_OBJECT_LENGTH(lengthWord);
        PolyWord *baseAddr = (PolyWord*)obj;
    
        if (OBJ_IS_CODE_OBJECT(lengthWord))
        {
            // Scan constants within the code.
            machineDependent->ScanConstantsWithinCode(obj, obj, length, this);
        
            // Skip to the constants and get ready to scan them.
            obj->GetConstSegmentForCode(length, baseAddr, length);

        } // else it's a normal object,

        PolyWord *endWord = baseAddr + length;

        // We want to minimise the actual recursion we perform so we try to
        // use tail recursion if we can.  We first scan from the end and
        // remove any words that don't need recursion.
        POLYUNSIGNED lastLengthWord = 0;
        while (endWord != baseAddr)
        {
            PolyWord wordAt = endWord[-1];
            if (IS_INT(wordAt) || wordAt == PolyWord::FromUnsigned(0))
                endWord--; // Don't need to look at this.
            else if ((lastLengthWord = ScanAddressAt(endWord-1)) != 0)
                // We need to process this one
                break;
            else endWord--; // We're not interested in this.
        }

        if (endWord == baseAddr)
            return; // We've done everything.

        // There is at least one word that needs to be processed, the
        // one at endWord-1.
        // Now process from the beginning forward to see if there are
        // any words before this that need to be handled.  This way we are more
        // likely to handle the head of a list by recursion and the
        // tail by looping (tail recursion).
        while (baseAddr < endWord-1)
        {
            PolyWord wordAt = *baseAddr;
            if (IS_INT(wordAt) || wordAt == PolyWord::FromUnsigned(0))
                baseAddr++; // Don't need to look at this.
            else
            {
                POLYUNSIGNED lengthWord = ScanAddressAt(baseAddr);
                if (lengthWord != 0)
                {
                    wordAt = *baseAddr; // Reload because it may have been side-effected
                     // We really have to process this recursively.
                    if (wordAt.IsCodePtr())
                        ScanAddressesInObject(ObjCodePtrToPtr(wordAt.AsCodePtr()), lengthWord);
                    else
                        ScanAddressesInObject(wordAt.AsObjPtr(), lengthWord);
                    baseAddr++;
                }
                else baseAddr++;
            }
        }

        // Finally process the last word we found that has to be processed.
        // Do this by looping rather than recursion.
        PolyWord wordAt = *baseAddr; // Last word to do.
        // This must be an address 
        if (wordAt.IsCodePtr())
            obj = ObjCodePtrToPtr(wordAt.AsCodePtr());
        else
            obj = wordAt.AsObjPtr();

        lengthWord = lastLengthWord;

    } while(1);
}
Exemple #4
0
void ProcessAddToVector::ProcessRoot(PolyObject *root)
{
    // Mark the initial object
    AddObjectsToDepthVectors(root);

    // Process the stack until it's empty.
    while (asp != 0)
    {
        // Pop it from the stack.
        PolyObject *obj = addStack[asp-1];

        if (obj->IsCodeObject())
        {
            /* There's a problem sharing code objects if they have relative calls/jumps
               in them to other code.  The code of two functions may be identical (e.g.
               they both call functions 100 bytes ahead) and so they will appear the
               same but if the functions they jump to are different they are actually
               different.  For that reason we don't share code segments.  DCJM 4/1/01 */
            asp--; // Pop it because we'll process it completely
            ScanAddressesInObject(obj);
            // If it's local set the depth with the value zero.
            if (obj->LengthWord() & _OBJ_GC_MARK)
            {
                obj->SetLengthWord(obj->LengthWord() & (~_OBJ_GC_MARK));
                m_parent->AddToVector(0, obj->LengthWord() & (~_OBJ_GC_MARK), obj);
                obj->SetLengthWord(OBJ_SET_DEPTH(0)); // Now scanned
            }
        }

        else if ((obj->LengthWord() & _OBJ_GC_MARK) && ! obj->IsMutable())
        {
            POLYUNSIGNED depth = 0;
            POLYUNSIGNED length = obj->Length();
            PolyWord *pt = (PolyWord*)obj;
            unsigned osp = asp;

            while (length != 0 && osp == asp)
            {
                POLYUNSIGNED d = AddObjectsToDepthVectors(*pt);
                if (d > depth) depth = d;
                pt++;
                length--;
            }

            if (osp == asp)
            {
                // We've finished it
                asp--; // Pop this item.
                depth++; // One more for this object
                obj->SetLengthWord(obj->LengthWord() & (~_OBJ_GC_MARK));
                m_parent->AddToVector(depth, obj->LengthWord() & (~_OBJ_GC_MARK), obj);
                obj->SetLengthWord(OBJ_SET_DEPTH(depth));
            }
        }

        else
        {
            POLYUNSIGNED length = obj->Length();
            PolyWord *pt = (PolyWord*)obj;
            unsigned osp = asp;

            while (length != 0)
            {
                if (! (*pt).IsTagged())
                {
                    // If we've already pushed an address break now
                    if (osp != asp) break;
                    // Process the address and possibly push it
                    AddObjectsToDepthVectors(*pt);
                }
                pt++;
                length--;
            }

            if (length == 0)
            {
                // We've finished it
                if (osp != asp)
                {
                    ASSERT(osp == asp-1);
                    addStack[osp-1] = addStack[osp];
                }
                asp--; // Pop this item.
                if (obj->LengthWord() & _OBJ_GC_MARK)
                    obj->SetLengthWord(OBJ_SET_DEPTH(0));
            }
        }
    }
}
Exemple #5
0
 // Have to redefine this for some reason.
 void ScanAddressesInObject(PolyObject *base)
     { ScanAddressesInObject(base, base->LengthWord()); }