コード例 #1
0
/* Mark all objects referred to by the ClassObject.
 */
static void scanClassObject(const ClassObject *clazz, GcMarkContext *ctx)
{
    LOGV_SCAN("---------> %s\n", clazz->name);

    if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) {
        /* We're an array; mark the class object of the contents
         * of the array.
         *
         * Note that we won't necessarily reach the array's element
         * class by scanning the array contents;  the array may be
         * zero-length, or may only contain null objects.
         */
        markObjectNonNull((Object *)clazz->elementClass, ctx);
    }

    /* We scan these explicitly in case the only remaining
     * reference to a particular class object is via a data
     * object;  we may not be guaranteed to reach all
     * live class objects via a classloader.
     */
    markObject((Object *)clazz->super, ctx);  // may be NULL (java.lang.Object)
    markObject(clazz->classLoader, ctx);      // may be NULL

    scanStaticFields(clazz, ctx);
    markInterfaces(clazz, ctx);
}
コード例 #2
0
/* Mark all objects referred to by a DataObject's instance fields.
 */
static void scanInstanceFields(const DataObject *obj, ClassObject *clazz,
        GcMarkContext *ctx)
{
//TODO: Optimize this by avoiding walking the superclass chain
    while (clazz != NULL) {
        InstField *f;
        int i;

        /* All of the fields that contain object references
         * are guaranteed to be at the beginning of the ifields list.
         */
        f = clazz->ifields;
        for (i = 0; i < clazz->ifieldRefCount; i++) {
            /* Mark the array or object reference.
             * May be NULL.
             *
             * Note that, per the comment on struct InstField,
             * f->byteOffset is the offset from the beginning of
             * obj, not the offset into obj->instanceData.
             */
            markObject(dvmGetFieldObject((Object*)obj, f->byteOffset), ctx);
            f++;
        }

        /* This will be NULL when we hit java.lang.Object
         */
        clazz = clazz->super;
    }
}
コード例 #3
0
ファイル: MemoryManager.cpp プロジェクト: ronsaldo/lodtalk
void GarbageCollector::mark()
{
	// Mark from the root objects.
	onRootsDo([this](Oop root) {
		markObject(root);
	});
}
コード例 #4
0
ファイル: LoadImage.cpp プロジェクト: brunobuzzi/Dolphin
template <MWORD ImageNullTerms> HRESULT ObjectMemory::LoadPointers(ibinstream& imageFile, const ImageHeader* pHeader, size_t& cbRead)
{
	ASSERT(pHeader->nGlobalPointers == NumPointers);

	::ZeroMemory(m_pConstObjs, CONSTSPACESIZE);

	size_t cbPerm = 0;
	BYTE* pNextConst = reinterpret_cast<BYTE*>(m_pConstObjs);
	int i;
	for (i = 0; i < NumPermanent; i++)
	{
		VariantObject* pConstObj = reinterpret_cast<VariantObject*>(pNextConst);

		OTE* ote = m_pOT + i;
		MWORD bytesToRead;
		MWORD allocSize;
		if (ote->isNullTerminated())
		{
			MWORD byteSize = ote->getSize();
			allocSize = byteSize + NULLTERMSIZE;
			bytesToRead = byteSize + ImageNullTerms;
		}
		else
		{
			allocSize = bytesToRead = ote->getSize();
		}

		if (bytesToRead > 0)
		{
			// Now load the rest of the object (size includes itself)
			if (!imageFile.read(&(pConstObj->m_fields), bytesToRead))
				return ImageReadError(imageFile);
		}
		else
		{
			if (allocSize == 0) pConstObj = NULL;
		}

		cbPerm += bytesToRead;
		pNextConst += _ROUND2(allocSize, 4);

		markObject(ote);
		Oop* oldLocation = reinterpret_cast<Oop*>(ote->m_location);
		ote->m_location = pConstObj;

		ote->beSticky();
		// Repair the object
		FixupObject(ote, oldLocation, pHeader);
	}

#ifdef _DEBUG
	TRACESTREAM << i<< L" permanent objects loaded totalling " << cbPerm<< L" bytes" << std::endl;
#endif

	memcpy(const_cast<VMPointers*>(&Pointers), &_Pointers, sizeof(Pointers));

	cbRead += cbPerm;
	return S_OK;
}
コード例 #5
0
ファイル: MemoryManager.cpp プロジェクト: ronsaldo/lodtalk
void GarbageCollector::markObject(Oop objectPointer)
{
	// TODO: Use the schorr-waite algorithm.

	// mark pointer objects.
	if(!objectPointer.isPointer())
		return;

	// Get the object header.
	auto header = objectPointer.header;
	if(header->gcColor)
		return;

	// Mark gray
	header->gcColor = Gray;

	// Mark recursively the children
	auto format = header->objectFormat;
	if(format == OF_FIXED_SIZE ||
	   format == OF_VARIABLE_SIZE_NO_IVARS ||
	   format == OF_VARIABLE_SIZE_IVARS)
	{
		auto slotCount = header->slotCount;
		auto headerSize = sizeof(ObjectHeader);
		if(slotCount == 255)
            slotCount = reinterpret_cast<uint64_t*> (header)[-1];

		// Traverse the slots.
		auto slots = reinterpret_cast<Oop*> (objectPointer.pointer + headerSize);
		for(size_t i = 0; i < slotCount; ++i)
			markObject(slots[i]);
	}

	// Special handilng of compiled method literals
	if(format >= OF_COMPILED_METHOD)
	{
		auto compiledMethod = reinterpret_cast<CompiledMethod*> (objectPointer.pointer);
		auto literalCount = compiledMethod->getLiteralCount();
		auto literals = compiledMethod->getFirstLiteralPointer();
		for(size_t i = 0; i < literalCount; ++i)
			markObject(literals[i]);
	}

	// Mark as black before ending.
	header->gcColor = Black;
}
コード例 #6
0
/* Mark all objects referred to by a DataObject's instance fields.
 */
static void scanInstanceFields(const DataObject *obj, ClassObject *clazz,
        GcMarkContext *ctx)
{
    if (clazz->refOffsets != CLASS_WALK_SUPER) {
        unsigned int refOffsets = clazz->refOffsets;
        while (refOffsets != 0) {
            const int rshift = CLZ(refOffsets);
            refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
            markObject(dvmGetFieldObject((Object*)obj,
                                         CLASS_OFFSET_FROM_CLZ(rshift)), ctx);
        }
    } else {
コード例 #7
0
/* Mark all objects referred to by the array's contents.
 */
static void scanObjectArray(const ArrayObject *array, GcMarkContext *ctx)
{
    Object **contents;
    u4 length;
    u4 i;

    contents = (Object **)array->contents;
    length = array->length;

    for (i = 0; i < length; i++) {
        markObject(*contents, ctx); // may be NULL
        contents++;
    }
}
コード例 #8
0
/*
 * Scans instance fields.
 */
static void scanInstanceFields(const Object *obj, GcMarkContext *ctx)
{
    assert(obj != NULL);
    assert(obj->clazz != NULL);
    assert(ctx != NULL);

    if (obj->clazz->refOffsets != CLASS_WALK_SUPER) {
        unsigned int refOffsets = obj->clazz->refOffsets;
        while (refOffsets != 0) {
            const int rshift = CLZ(refOffsets);
            refOffsets &= ~(CLASS_HIGH_BIT >> rshift);
            markObject(dvmGetFieldObject((Object*)obj,
                                          CLASS_OFFSET_FROM_CLZ(rshift)), ctx);
        }
    } else {
コード例 #9
0
/* Mark all objects referred to by a ClassObject's static fields.
 */
static void scanStaticFields(const ClassObject *clazz, GcMarkContext *ctx)
{
    StaticField *f;
    int i;

    //TODO: Optimize this with a bit vector or something
    f = clazz->sfields;
    for (i = 0; i < clazz->sfieldCount; i++) {
        char c = f->field.signature[0];
        if (c == '[' || c == 'L') {
            /* It's an array or class reference.
             */
            markObject((Object *)f->value.l, ctx);
        }
        f++;
    }
}
コード例 #10
0
ファイル: LoadImage.cpp プロジェクト: brunobuzzi/Dolphin
template <MWORD ImageNullTerms> HRESULT ObjectMemory::LoadObjects(ibinstream & imageFile, const ImageHeader * pHeader, size_t & cbRead)
{
	// Other free OTEs will be threaded in front of the first OTE off the end
	// of the currently committed table space. We set the free list pointer
	// to that OTE rather than NULL to distinguish attemps to access off the
	// end of the current table, which then allows us to dynamically grow it
	// on demand
	OTE* pEnd = m_pOT + pHeader->nTableSize;
	m_pFreePointerList = reinterpret_cast<OTE*>(pEnd);

#ifdef _DEBUG
	unsigned numObjects = NumPermanent;	// Allow for VM registry, etc!
	m_nFreeOTEs = m_nOTSize - pHeader->nTableSize;
#endif

	size_t nDataSize = 0;
	for (OTE* ote = m_pOT + NumPermanent; ote < pEnd; ote++)
	{
		if (!ote->isFree())
		{
			MWORD byteSize = ote->getSize();

			MWORD* oldLocation = reinterpret_cast<MWORD*>(ote->m_location);

			Object* pBody;

			// Allocate space for the object, and copy into that space
			if (ote->heapSpace() == OTEFlags::VirtualSpace)
			{
				MWORD dwMaxAlloc;
				if (!imageFile.read(&dwMaxAlloc, sizeof(MWORD)))
					return ImageReadError(imageFile);
				cbRead += sizeof(MWORD);

				pBody = reinterpret_cast<Object*>(AllocateVirtualSpace(dwMaxAlloc, byteSize));
				ote->m_location = pBody;
			}
			else
			{
				if (ote->isNullTerminated())
				{
					ASSERT(!ote->isPointers());
					pBody = AllocObj(ote, byteSize + NULLTERMSIZE);
					if (NULLTERMSIZE > ImageNullTerms)
					{
						// Ensure we have a full null-terminator
						*reinterpret_cast<NULLTERMTYPE*>(static_cast<VariantByteObject*>(pBody)->m_fields+byteSize) = 0;
					}
					byteSize += ImageNullTerms;
				}
				else
				{
					pBody = AllocObj(ote, byteSize);
				}

			}

			markObject(ote);
			if (!imageFile.read(pBody, byteSize))
				return ImageReadError(imageFile);

			cbRead += byteSize;
			FixupObject(ote, oldLocation, pHeader);

#ifdef _DEBUG
			numObjects++;
#endif
		}
		else
		{
			// Thread onto the free list
			ote->m_location = (reinterpret_cast<POBJECT>(m_pFreePointerList));
			m_pFreePointerList = ote;
#ifdef _DEBUG
			m_nFreeOTEs++;
#endif
		}
	}

	// Note that we don't terminate the free list with a null, because
	// it must point off into space in order to get a GPF when it
	// needs to be expanded (at which point we commit more pages)

#ifdef _DEBUG
	ASSERT(numObjects + m_nFreeOTEs == m_nOTSize);
	ASSERT(m_nFreeOTEs = CountFreeOTEs());
	TRACESTREAM << std::dec << numObjects<< L", " << m_nFreeOTEs<< L" free" << std::endl;
#endif

	cbRead += nDataSize;
	return S_OK;
}