コード例 #1
0
ファイル: heap.c プロジェクト: BackupGGCode/megapython
/*
 * Marks the root objects so they won't be collected during the sweep phase.
 * Recursively marks all objects reachable from the roots.
 */
static PmReturn_t
heap_gcMarkRoots(void)
{
    PmReturn_t retval;

    /* Toggle the GC marking value so it differs from the last run */
    pmHeap.gcval ^= 1;

    /* Mark the constant objects */
    retval = heap_gcMarkObj(PM_NONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_ZERO);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_ONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_NEGONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_CODE_STR);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the image info struct nodes and their contents */
    retval = heap_gcMarkObj((pPmObj_t)gVmGlobal.pimglist);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the builtins dict */
    retval = heap_gcMarkObj(PM_PBUILTINS);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the native frame if it is active */
    retval = heap_gcMarkObj((pPmObj_t)&gVmGlobal.nativeframe);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the thread list */
    retval = heap_gcMarkObj((pPmObj_t)gVmGlobal.threadList);

    /* Mark the callback dict */
    retval = heap_gcMarkObj((pPmObj_t)gVmGlobal.callbacks);

    return retval;
}
コード例 #2
0
ファイル: heap.c プロジェクト: 01iv3r/OpenPilot
/*
 * Marks the root objects so they won't be collected during the sweep phase.
 * Recursively marks all objects reachable from the roots.
 */
static PmReturn_t
heap_gcMarkRoots(void)
{
    PmReturn_t retval;
    uint8_t i;

    /* Toggle the GC marking value so it differs from the last run */
    pmHeap.gcval ^= 1;

    /* Mark the constant objects */
    retval = heap_gcMarkObj(PM_NONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_FALSE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_TRUE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_ZERO);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_ONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_NEGONE);
    PM_RETURN_IF_ERROR(retval);
    retval = heap_gcMarkObj(PM_CODE_STR);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the builtins dict */
    retval = heap_gcMarkObj(PM_PBUILTINS);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the native frame if it is active */
    retval = heap_gcMarkObj((pPmObj_t)&gVmGlobal.nativeframe);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the thread list */
    retval = heap_gcMarkObj((pPmObj_t)gVmGlobal.threadList);
    PM_RETURN_IF_ERROR(retval);

    /* Mark the temporary roots */
    for (i = 0; i < pmHeap.temp_root_index; i++)
    {
        retval = heap_gcMarkObj(pmHeap.temp_roots[i]);
        PM_RETURN_IF_ERROR(retval);
    }

    return retval;
}
コード例 #3
0
ファイル: heap.c プロジェクト: 01iv3r/OpenPilot
/*
 * Marks the given object and the objects it references.
 *
 * @param   pobj Any non-free heap object
 * @return  Return code
 */
static PmReturn_t
heap_gcMarkObj(pPmObj_t pobj)
{
    PmReturn_t retval = PM_RET_OK;
    int16_t i = 0;
    int16_t n;
    PmType_t type;

    /* Return if ptr is null or object is already marked */
    if (pobj == C_NULL)
    {
        return retval;
    }
    if (OBJ_GET_GCVAL(pobj) == pmHeap.gcval)
    {
        return retval;
    }

    /* The pointer must be within the heap (native frame is special case) */
    C_ASSERT((((uint8_t *)pobj >= &pmHeap.base[0])
              && ((uint8_t *)pobj <= &pmHeap.base[PM_HEAP_SIZE]))
             || ((uint8_t *)pobj == (uint8_t *)&gVmGlobal.nativeframe));

    /* The object must not already be free */
    C_ASSERT(OBJ_GET_FREE(pobj) == 0);

    type = (PmType_t)OBJ_GET_TYPE(pobj);
    switch (type)
    {
            /* Objects with no references to other objects */
        case OBJ_TYPE_NON:
        case OBJ_TYPE_INT:
        case OBJ_TYPE_FLT:
        case OBJ_TYPE_STR:
        case OBJ_TYPE_NOB:
        case OBJ_TYPE_BOOL:
        case OBJ_TYPE_CIO:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;

        case OBJ_TYPE_TUP:
            i = ((pPmTuple_t)pobj)->length;

            /* Mark tuple head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in tuple */
            while (--i >= 0)
            {
                retval = heap_gcMarkObj(((pPmTuple_t)pobj)->val[i]);
                PM_RETURN_IF_ERROR(retval);
            }
            break;

        case OBJ_TYPE_LST:

            /* Mark the list */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmList_t)pobj)->val);
            break;

        case OBJ_TYPE_DIC:
            /* Mark the dict head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the keys seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_keys);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the vals seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_vals);
            break;

        case OBJ_TYPE_COB:
            /* Mark the code obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the names tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_names);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the consts tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_consts);
            PM_RETURN_IF_ERROR(retval);

            /* #122: Mark the code image if it is in RAM */
            if (((pPmCo_t)pobj)->co_memspace == MEMSPACE_RAM)
            {
                retval = heap_gcMarkObj((pPmObj_t)
                                        (((pPmCo_t)pobj)->co_codeimgaddr));
                PM_RETURN_IF_ERROR(retval);
            }

#ifdef HAVE_CLOSURES
            /* #256: Add support for closures */
            /* Mark the cellvars tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_cellvars);
#endif /* HAVE_CLOSURES */
            break;

        case OBJ_TYPE_MOD:
        case OBJ_TYPE_FXN:
            /* Module and Func objs are implemented via the PmFunc_t */
            /* Mark the func obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the code obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_co);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attr dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_globals);
            PM_RETURN_IF_ERROR(retval);

#ifdef HAVE_DEFAULTARGS
            /* Mark the default args tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_defaultargs);
            PM_RETURN_IF_ERROR(retval);
#endif /* HAVE_DEFAULTARGS */

#ifdef HAVE_CLOSURES
            /* #256: Mark the closure tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_closure);
#endif /* HAVE_CLOSURES */
            break;

#ifdef HAVE_CLASSES
        case OBJ_TYPE_CLI:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the class */
            retval = heap_gcMarkObj((pPmObj_t)((pPmInstance_t)pobj)->cli_class);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs);
            break;

        case OBJ_TYPE_MTH:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the instance */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_instance);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the func */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->m_attrs);
            break;

        case OBJ_TYPE_CLO:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->cl_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the base tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->cl_bases);
            break;
#endif /* HAVE_CLASSES */

            /*
             * An obj in ram should not be of these types.
             * Images arrive in RAM as string objects (image is array of bytes)
             */
        case OBJ_TYPE_CIM:
        case OBJ_TYPE_NIM:
            PM_RAISE(retval, PM_RET_EX_SYS);
            return retval;

        case OBJ_TYPE_FRM:
        {
            pPmObj_t *ppobj2 = C_NULL;

            /* Mark the frame obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the previous frame, if this isn't a generator's frame */
            /* Issue #129: Fix iterator losing its object */
            if ((((pPmFrame_t)pobj)->fo_func->f_co->co_flags & CO_GENERATOR) == 0)
            {
                retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_back);
                PM_RETURN_IF_ERROR(retval);
            }

            /* Mark the fxn obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the blockstack */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFrame_t)pobj)->fo_blockstack);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_globals);
            PM_RETURN_IF_ERROR(retval);

            /* Mark each obj in the locals list and the stack */
            ppobj2 = ((pPmFrame_t)pobj)->fo_locals;
            while (ppobj2 < ((pPmFrame_t)pobj)->fo_sp)
            {
                retval = heap_gcMarkObj(*ppobj2);
                PM_RETURN_IF_ERROR(retval);
                ppobj2++;
            }
            break;
        }

        case OBJ_TYPE_BLK:
            /* Mark the block obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the next block in the stack */
            retval = heap_gcMarkObj((pPmObj_t)((pPmBlock_t)pobj)->next);
            break;

        case OBJ_TYPE_SGL:
            /* Mark the seglist obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist's segments */
            n = ((pSeglist_t)pobj)->sl_length;
            pobj = (pPmObj_t)((pSeglist_t)pobj)->sl_rootseg;
            for (i = 0; i < n; i++)
            {
                /* Mark the segment item */
                retval = heap_gcMarkObj(((pSegment_t)pobj)->s_val[i % SEGLIST_OBJS_PER_SEG]);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the segment obj head */
                if ((i % SEGLIST_OBJS_PER_SEG) == 0)
                {
                    OBJ_SET_GCVAL(pobj, pmHeap.gcval);
                }

                /* Point to the next segment */
                else
                if ((i % SEGLIST_OBJS_PER_SEG) == (SEGLIST_OBJS_PER_SEG - 1))
                {
                    pobj = (pPmObj_t)((pSegment_t)pobj)->next;
                    if (pobj == C_NULL)
                    {
                        break;
                    }
                }
            }
            break;

        case OBJ_TYPE_SQI:
            /* Mark the sequence iterator obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the sequence */
            retval = heap_gcMarkObj(((pPmSeqIter_t)pobj)->si_sequence);
            break;

        case OBJ_TYPE_THR:
            /* Mark the thread obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the current frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmThread_t)pobj)->pframe);
            break;

        case OBJ_TYPE_NFM:
            /*
             * Mark the obj desc.  This doesn't really do much since the
             * native frame is declared static (not from the heap), but this
             * is here in case that ever changes
             */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the native frame's remaining fields if active */
            if (gVmGlobal.nativeframe.nf_active)
            {
                /* Mark the frame stack */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_back);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the function object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_func);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the stack object */
                retval = heap_gcMarkObj(gVmGlobal.nativeframe.nf_stack);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the args to the native func */
                for (i = 0; i < NATIVE_GET_NUM_ARGS(); i++)
                {
                    retval =
                        heap_gcMarkObj(gVmGlobal.nativeframe.nf_locals[i]);
                    PM_RETURN_IF_ERROR(retval);
                }
            }
            break;

#ifdef HAVE_BYTEARRAY
        case OBJ_TYPE_BYA:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            retval = heap_gcMarkObj((pPmObj_t)((pPmBytearray_t)pobj)->val);
            break;

        case OBJ_TYPE_BYS:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;
#endif /* HAVE_BYTEARRAY */

        default:
            /* There should be no invalid types */
            PM_RAISE(retval, PM_RET_EX_SYS);
            break;
    }
    return retval;
}
コード例 #4
0
ファイル: heap.c プロジェクト: BackupGGCode/megapython
/*
 * Marks the given object and the objects it references.
 *
 * @param   pobj Any non-free heap object
 * @return  Return code
 */
static PmReturn_t
heap_gcMarkObj(pPmObj_t pobj)
{
    PmReturn_t retval = PM_RET_OK;
    int16_t i = 0;
    PmType_t type;

    /* Return if ptr is null or object is already marked */
    if ((pobj == C_NULL) || (OBJ_GET_GCVAL(pobj) == pmHeap.gcval))
    {
        return retval;
    }

    /* The pointer must be within the heap (native frame is special case) */
    C_ASSERT((((uint8_t *)pobj >= &pmHeap.base[0])
             && ((uint8_t *)pobj <= &pmHeap.base[HEAP_SIZE]))
             || ((uint8_t *)pobj == (uint8_t *)&gVmGlobal.nativeframe));

    /* The object must not already be free */
    C_ASSERT(OBJ_GET_FREE(pobj) == 0);

    type = OBJ_GET_TYPE(pobj);
    /*if (type == 0x03){
	printf("came across string; value is ");
	string_print(pobj,0);
	printf("\n");
    }*/
    switch (type)
    {
        /* Objects with no references to other objects */
        case OBJ_TYPE_NON:
        case OBJ_TYPE_INT:
        case OBJ_TYPE_FLT:
        case OBJ_TYPE_NOB:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
            break;

        case OBJ_TYPE_STR:
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);
#if USE_STRING_CACHE
            retval = heap_gcMarkObj((pPmObj_t)((pPmString_t)pobj)->next);
#endif
            break;

        case OBJ_TYPE_TUP:
            i = ((pPmTuple_t)pobj)->length;

            /* Mark tuple head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in tuple */
            while (--i >= 0)
            {
                retval = heap_gcMarkObj(((pPmTuple_t)pobj)->val[i]);
                PM_RETURN_IF_ERROR(retval);
            }
            break;

        case OBJ_TYPE_LST:

            /* Mark the list */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmList_t)pobj)->val);
            break;

        case OBJ_TYPE_DIC:
            /* Mark the dict head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the keys seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_keys);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the vals seglist */
            retval = heap_gcMarkObj((pPmObj_t)((pPmDict_t)pobj)->d_vals);
            break;

        case OBJ_TYPE_COB:
            /* Mark the code obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the names tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_names);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the consts tuple */
            retval = heap_gcMarkObj((pPmObj_t)((pPmCo_t)pobj)->co_consts);
            PM_RETURN_IF_ERROR(retval);

            /* #122: Mark the code image if it is in RAM */
            if (((pPmCo_t)pobj)->co_memspace == MEMSPACE_RAM)
            {
                /* Special case: The image is contained in a string object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        (((pPmCo_t)pobj)->co_codeimgaddr
                                         - sizeof(PmObjDesc_t)));
            }
            break;

        case OBJ_TYPE_MOD:
        case OBJ_TYPE_FXN:
            /* Module and Func objs are implemented via the PmFunc_t */
            /* Mark the func obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the code obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_co);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attr dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFunc_t)pobj)->f_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the default args tuple */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFunc_t)pobj)->f_defaultargs);
            break;

        case OBJ_TYPE_CLO:
        case OBJ_TYPE_CLI:
        case OBJ_TYPE_EXN:
            /* Mark the obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the name */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->name);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the bases */
            retval = heap_gcMarkObj((pPmObj_t)((pPmClass_t)pobj)->bases);
            break;

        /*
         * An obj in ram should not be of these types.
         * Images arrive in RAM as string objects (image is array of bytes)
         */
        case OBJ_TYPE_CIM:
        case OBJ_TYPE_NIM:
            PM_RAISE(retval, PM_RET_EX_SYS);
            return retval;

        case OBJ_TYPE_FRM:
        {
            pPmObj_t *ppobj2 = C_NULL;

            /* Mark the frame obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the previous frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_back);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the fxn obj */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_func);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the blockstack */
            retval = heap_gcMarkObj((pPmObj_t)
                                    ((pPmFrame_t)pobj)->fo_blockstack);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the attrs dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_attrs);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the globals dict */
            retval = heap_gcMarkObj((pPmObj_t)((pPmFrame_t)pobj)->fo_globals);
            PM_RETURN_IF_ERROR(retval);

            /* Mark each obj in the locals list and the stack */
            ppobj2 = ((pPmFrame_t)pobj)->fo_locals;
            while (ppobj2 < ((pPmFrame_t)pobj)->fo_sp)
            {
                retval = heap_gcMarkObj(*ppobj2);
                PM_RETURN_IF_ERROR(retval);
                ppobj2++;
            }
            break;
        }

        case OBJ_TYPE_BLK:
            /* Mark the block obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the next block in the stack */
            retval = heap_gcMarkObj((pPmObj_t)((pPmBlock_t)pobj)->next);
            break;

        case OBJ_TYPE_SEG:
            /* Mark the segment obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark each obj in the segment */
            for (i = 0; i < SEGLIST_OBJS_PER_SEG; i++)
            {
                retval = heap_gcMarkObj(((pSegment_t)pobj)->s_val[i]);
                PM_RETURN_IF_ERROR(retval);
            }

            /* Mark the next segment */
            retval = heap_gcMarkObj((pPmObj_t)((pSegment_t)pobj)->next);
            break;

        case OBJ_TYPE_SGL:
            /* Mark the seglist obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the root segment */
            retval = heap_gcMarkObj((pPmObj_t)((pSeglist_t)pobj)->sl_rootseg);
            break;

        case OBJ_TYPE_SQI:
            /* Mark the sequence iterator obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the sequence */
            retval = heap_gcMarkObj(((pPmSeqIter_t)pobj)->si_sequence);
            break;

        case OBJ_TYPE_THR:
            /* Mark the thread obj head */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the current frame */
            retval = heap_gcMarkObj((pPmObj_t)((pPmThread_t)pobj)->pframe);
            break;

        case OBJ_TYPE_NFM:
            /*
             * Mark the obj desc.  This doesn't really do much since the
             * native frame is declared static (not from the heap), but this
             * is here in case that ever changes
             */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the native frame's fields if it is active */
            if (gVmGlobal.nativeframe.nf_active)
            {
                /* Mark the frame stack */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_back);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the function object */
                retval = heap_gcMarkObj((pPmObj_t)
                                        gVmGlobal.nativeframe.nf_func);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the stack object */
                retval = heap_gcMarkObj(gVmGlobal.nativeframe.nf_stack);
                PM_RETURN_IF_ERROR(retval);

                /* Mark the args to the native func */
                for (i = 0; i < NATIVE_GET_NUM_ARGS(); i++)
                {
                    retval = heap_gcMarkObj(gVmGlobal.nativeframe
                                            .nf_locals[i]);
                    PM_RETURN_IF_ERROR(retval);
                }
            }
            break;

        case OBJ_TYPE_IIS:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the name string */
            retval = heap_gcMarkObj((pPmObj_t)((pPmImgInfo_t)pobj)->ii_name);
            PM_RETURN_IF_ERROR(retval);

            /* Mark the next node in the list */
            retval = heap_gcMarkObj((pPmObj_t)((pPmImgInfo_t)pobj)->next);
            break;

        case OBJ_TYPE_SLC:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the indices */
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->start);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->end);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmSlice_t)pobj)->step);
            PM_RETURN_IF_ERROR(retval);

            break;
        case OBJ_TYPE_MTH:
            /* Mark the obj desc */
            OBJ_SET_GCVAL(pobj, pmHeap.gcval);

            /* Mark the function and self */
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->self);
            PM_RETURN_IF_ERROR(retval);
            retval = heap_gcMarkObj((pPmObj_t)((pPmMethod_t)pobj)->func);
            PM_RETURN_IF_ERROR(retval);

            break;
    }
    return retval;
}